mirror of
https://github.com/OpenMW/openmw.git
synced 2025-10-15 08:56:35 +00:00
Merge branch 'skibidi-dop-doppler' into 'master'
Doppler, take two See merge request OpenMW/openmw!4660
This commit is contained in:
commit
aae81264a2
23 changed files with 180 additions and 31 deletions
|
@ -291,6 +291,7 @@ bool Launcher::SettingsPage::loadSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox);
|
loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox);
|
||||||
|
dopplerSpinBox->setValue(Settings::sound().mDopplerFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface Changes
|
// Interface Changes
|
||||||
|
@ -482,6 +483,8 @@ void Launcher::SettingsPage::saveSettings()
|
||||||
|
|
||||||
const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked;
|
const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked;
|
||||||
Settings::sound().mCameraListener.set(cCameraListener);
|
Settings::sound().mCameraListener.set(cCameraListener);
|
||||||
|
|
||||||
|
Settings::sound().mDopplerFactor.set(dopplerSpinBox->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface Changes
|
// Interface Changes
|
||||||
|
|
|
@ -1224,6 +1224,51 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="dopplerLabel">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Controls the strength of the Doppler effect. Zero means it is completely disabled.</p><p>The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Doppler Factor</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="dopplerSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>283</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.250000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
|
@ -234,6 +234,8 @@ namespace MWBase
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater)
|
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
|
virtual void setListenerVel(const osg::Vec3f& vel) = 0;
|
||||||
|
|
||||||
virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0;
|
virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0;
|
||||||
|
|
||||||
void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; }
|
void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; }
|
||||||
|
|
|
@ -496,6 +496,8 @@ namespace MWBase
|
||||||
virtual float getSunVisibility() const = 0;
|
virtual float getSunVisibility() const = 0;
|
||||||
virtual float getSunPercentage() const = 0;
|
virtual float getSunPercentage() const = 0;
|
||||||
|
|
||||||
|
virtual float getPhysicsFrameRateDt() const = 0;
|
||||||
|
|
||||||
virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
||||||
|
|
||||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||||
|
|
|
@ -93,9 +93,10 @@ namespace
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> parentNode)
|
PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> parentNode)
|
||||||
: mShapeManager(
|
: mPhysicsDt(1.f / 60.f)
|
||||||
std::make_unique<Resource::BulletShapeManager>(resourceSystem->getVFS(), resourceSystem->getSceneManager(),
|
, mShapeManager(std::make_unique<Resource::BulletShapeManager>(resourceSystem->getVFS(),
|
||||||
resourceSystem->getNifFileManager(), Settings::cells().mCacheExpiryDelay))
|
resourceSystem->getSceneManager(), resourceSystem->getNifFileManager(),
|
||||||
|
Settings::cells().mCacheExpiryDelay))
|
||||||
, mResourceSystem(resourceSystem)
|
, mResourceSystem(resourceSystem)
|
||||||
, mDebugDrawEnabled(false)
|
, mDebugDrawEnabled(false)
|
||||||
, mTimeAccum(0.0f)
|
, mTimeAccum(0.0f)
|
||||||
|
@ -103,7 +104,6 @@ namespace MWPhysics
|
||||||
, mWaterHeight(0)
|
, mWaterHeight(0)
|
||||||
, mWaterEnabled(false)
|
, mWaterEnabled(false)
|
||||||
, mParentNode(std::move(parentNode))
|
, mParentNode(std::move(parentNode))
|
||||||
, mPhysicsDt(1.f / 60.f)
|
|
||||||
{
|
{
|
||||||
mResourceSystem->addResourceManager(mShapeManager.get());
|
mResourceSystem->addResourceManager(mShapeManager.get());
|
||||||
|
|
||||||
|
|
|
@ -287,6 +287,8 @@ namespace MWPhysics
|
||||||
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
|
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
|
||||||
void reportCollision(const btVector3& position, const btVector3& normal);
|
void reportCollision(const btVector3& position, const btVector3& normal);
|
||||||
|
|
||||||
|
float mPhysicsDt;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateWater();
|
void updateWater();
|
||||||
|
|
||||||
|
@ -330,8 +332,6 @@ namespace MWPhysics
|
||||||
|
|
||||||
osg::ref_ptr<osg::Group> mParentNode;
|
osg::ref_ptr<osg::Group> mParentNode;
|
||||||
|
|
||||||
float mPhysicsDt;
|
|
||||||
|
|
||||||
std::size_t mSimulationsCounter = 0;
|
std::size_t mSimulationsCounter = 0;
|
||||||
std::array<std::vector<Simulation>, 2> mSimulations;
|
std::array<std::vector<Simulation>, 2> mSimulations;
|
||||||
std::vector<std::pair<MWWorld::Ptr, osg::Vec3f>> mActorsPositions;
|
std::vector<std::pair<MWWorld::Ptr, osg::Vec3f>> mActorsPositions;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <components/misc/constants.hpp>
|
#include <components/misc/constants.hpp>
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
#include <components/misc/thread.hpp>
|
#include <components/misc/thread.hpp>
|
||||||
|
#include <components/settings/values.hpp>
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
|
||||||
#include "efxpresets.h"
|
#include "efxpresets.h"
|
||||||
|
@ -963,6 +964,7 @@ namespace MWSound
|
||||||
// Speed of sound is in units per second. Take the sound speed in air (assumed
|
// Speed of sound is in units per second. Take the sound speed in air (assumed
|
||||||
// meters per second), multiply by the units per meter to get the speed in u/s.
|
// meters per second), multiply by the units per meter to get the speed in u/s.
|
||||||
alSpeedOfSound(Constants::SoundSpeedInAir * Constants::UnitsPerMeter);
|
alSpeedOfSound(Constants::SoundSpeedInAir * Constants::UnitsPerMeter);
|
||||||
|
alDopplerFactor(Settings::sound().mDopplerFactor);
|
||||||
alGetError();
|
alGetError();
|
||||||
|
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
|
@ -1142,8 +1144,8 @@ namespace MWSound
|
||||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALOutput::initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist,
|
void OpenALOutput::initCommon3D(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat mindist,
|
||||||
ALfloat gain, ALfloat pitch, bool loop, bool useenv)
|
ALfloat maxdist, ALfloat gain, ALfloat pitch, bool loop, bool useenv)
|
||||||
{
|
{
|
||||||
alSourcef(source, AL_REFERENCE_DISTANCE, mindist);
|
alSourcef(source, AL_REFERENCE_DISTANCE, mindist);
|
||||||
alSourcef(source, AL_MAX_DISTANCE, maxdist);
|
alSourcef(source, AL_MAX_DISTANCE, maxdist);
|
||||||
|
@ -1179,11 +1181,11 @@ namespace MWSound
|
||||||
alSourcef(source, AL_PITCH, pitch);
|
alSourcef(source, AL_PITCH, pitch);
|
||||||
alSourcefv(source, AL_POSITION, pos.ptr());
|
alSourcefv(source, AL_POSITION, pos.ptr());
|
||||||
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSourcefv(source, AL_VELOCITY, vel.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALOutput::updateCommon(
|
void OpenALOutput::updateCommon(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat maxdist,
|
||||||
ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv)
|
ALfloat gain, ALfloat pitch, bool useenv)
|
||||||
{
|
{
|
||||||
if (useenv && mListenerEnv == Env_Underwater && !mWaterFilter)
|
if (useenv && mListenerEnv == Env_Underwater && !mWaterFilter)
|
||||||
{
|
{
|
||||||
|
@ -1195,7 +1197,7 @@ namespace MWSound
|
||||||
alSourcef(source, AL_PITCH, pitch);
|
alSourcef(source, AL_PITCH, pitch);
|
||||||
alSourcefv(source, AL_POSITION, pos.ptr());
|
alSourcefv(source, AL_POSITION, pos.ptr());
|
||||||
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSourcefv(source, AL_VELOCITY, vel.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenALOutput::playSound(Sound* sound, Sound_Handle data, float offset)
|
bool OpenALOutput::playSound(Sound* sound, Sound_Handle data, float offset)
|
||||||
|
@ -1248,8 +1250,9 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
source = mFreeSources.front();
|
source = mFreeSources.front();
|
||||||
|
|
||||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
initCommon3D(source, sound->getPosition(), sound->getVelocity(), sound->getMinDistance(),
|
||||||
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(), sound->getUseEnv());
|
sound->getMaxDistance(), sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(),
|
||||||
|
sound->getUseEnv());
|
||||||
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
||||||
alSourcef(source, AL_SEC_OFFSET, offset);
|
alSourcef(source, AL_SEC_OFFSET, offset);
|
||||||
if (getALError() != AL_NO_ERROR)
|
if (getALError() != AL_NO_ERROR)
|
||||||
|
@ -1312,8 +1315,8 @@ namespace MWSound
|
||||||
return;
|
return;
|
||||||
ALuint source = GET_PTRID(sound->mHandle);
|
ALuint source = GET_PTRID(sound->mHandle);
|
||||||
|
|
||||||
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
|
updateCommon(source, sound->getPosition(), sound->getVelocity(), sound->getMaxDistance(),
|
||||||
getTimeScaledPitch(sound), sound->getUseEnv());
|
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getUseEnv());
|
||||||
getALError();
|
getALError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1360,8 +1363,8 @@ namespace MWSound
|
||||||
if (sound->getIsLooping())
|
if (sound->getIsLooping())
|
||||||
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
|
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
|
||||||
|
|
||||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
initCommon3D(source, sound->getPosition(), sound->getVelocity(), sound->getMinDistance(),
|
||||||
sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv());
|
sound->getMaxDistance(), sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv());
|
||||||
if (getALError() != AL_NO_ERROR)
|
if (getALError() != AL_NO_ERROR)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1443,8 +1446,8 @@ namespace MWSound
|
||||||
OpenAL_SoundStream* stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
|
OpenAL_SoundStream* stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
|
||||||
ALuint source = stream->mSource;
|
ALuint source = stream->mSource;
|
||||||
|
|
||||||
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
|
updateCommon(source, sound->getPosition(), sound->getVelocity(), sound->getMaxDistance(),
|
||||||
getTimeScaledPitch(sound), sound->getUseEnv());
|
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getUseEnv());
|
||||||
getALError();
|
getALError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,12 +1462,13 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALOutput::updateListener(
|
void OpenALOutput::updateListener(
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env)
|
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, const osg::Vec3f& vel, Environment env)
|
||||||
{
|
{
|
||||||
if (mContext)
|
if (mContext)
|
||||||
{
|
{
|
||||||
ALfloat orient[6] = { atdir.x(), atdir.y(), atdir.z(), updir.x(), updir.y(), updir.z() };
|
ALfloat orient[6] = { atdir.x(), atdir.y(), atdir.z(), updir.x(), updir.y(), updir.z() };
|
||||||
alListenerfv(AL_POSITION, pos.ptr());
|
alListenerfv(AL_POSITION, pos.ptr());
|
||||||
|
alListenerfv(AL_VELOCITY, vel.ptr());
|
||||||
alListenerfv(AL_ORIENTATION, orient);
|
alListenerfv(AL_ORIENTATION, orient);
|
||||||
|
|
||||||
if (env != mListenerEnv)
|
if (env != mListenerEnv)
|
||||||
|
@ -1497,6 +1501,7 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
mListenerPos = pos;
|
mListenerPos = pos;
|
||||||
|
mListenerVel = vel;
|
||||||
mListenerEnv = env;
|
mListenerEnv = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1582,7 +1587,6 @@ namespace MWSound
|
||||||
: SoundOutput(mgr)
|
: SoundOutput(mgr)
|
||||||
, mDevice(nullptr)
|
, mDevice(nullptr)
|
||||||
, mContext(nullptr)
|
, mContext(nullptr)
|
||||||
, mListenerPos(0.0f, 0.0f, 0.0f)
|
|
||||||
, mListenerEnv(Env_Normal)
|
, mListenerEnv(Env_Normal)
|
||||||
, mWaterFilter(0)
|
, mWaterFilter(0)
|
||||||
, mWaterEffect(0)
|
, mWaterEffect(0)
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace MWSound
|
||||||
StreamVec mActiveStreams;
|
StreamVec mActiveStreams;
|
||||||
|
|
||||||
osg::Vec3f mListenerPos;
|
osg::Vec3f mListenerPos;
|
||||||
|
osg::Vec3f mListenerVel;
|
||||||
Environment mListenerEnv;
|
Environment mListenerEnv;
|
||||||
|
|
||||||
ALuint mWaterFilter;
|
ALuint mWaterFilter;
|
||||||
|
@ -64,11 +65,11 @@ namespace MWSound
|
||||||
std::unique_ptr<DefaultDeviceThread> mDefaultDeviceThread;
|
std::unique_ptr<DefaultDeviceThread> mDefaultDeviceThread;
|
||||||
|
|
||||||
void initCommon2D(ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
void initCommon2D(ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
||||||
void initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist, ALfloat gain,
|
void initCommon3D(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat mindist, ALfloat maxdist,
|
||||||
ALfloat pitch, bool loop, bool useenv);
|
ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
||||||
|
|
||||||
void updateCommon(
|
void updateCommon(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat maxdist, ALfloat gain,
|
||||||
ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv);
|
ALfloat pitch, bool useenv);
|
||||||
|
|
||||||
float getTimeScaledPitch(SoundBase* sound);
|
float getTimeScaledPitch(SoundBase* sound);
|
||||||
|
|
||||||
|
@ -108,8 +109,8 @@ namespace MWSound
|
||||||
void startUpdate() override;
|
void startUpdate() override;
|
||||||
void finishUpdate() override;
|
void finishUpdate() override;
|
||||||
|
|
||||||
void updateListener(
|
void updateListener(const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir,
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env) override;
|
const osg::Vec3f& vel, Environment env) override;
|
||||||
|
|
||||||
void pauseSounds(int types) override;
|
void pauseSounds(int types) override;
|
||||||
void resumeSounds(int types) override;
|
void resumeSounds(int types) override;
|
||||||
|
|
|
@ -31,6 +31,8 @@ namespace MWSound
|
||||||
struct SoundParams
|
struct SoundParams
|
||||||
{
|
{
|
||||||
osg::Vec3f mPos;
|
osg::Vec3f mPos;
|
||||||
|
osg::Vec3f mLastPos;
|
||||||
|
osg::Vec3f mVel;
|
||||||
float mVolume = 1.0f;
|
float mVolume = 1.0f;
|
||||||
float mBaseVolume = 1.0f;
|
float mBaseVolume = 1.0f;
|
||||||
float mPitch = 1.0f;
|
float mPitch = 1.0f;
|
||||||
|
@ -57,6 +59,8 @@ namespace MWSound
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setPosition(const osg::Vec3f& pos) { mParams.mPos = pos; }
|
void setPosition(const osg::Vec3f& pos) { mParams.mPos = pos; }
|
||||||
|
void setLastPosition(const osg::Vec3f& lastpos) { mParams.mLastPos = lastpos; }
|
||||||
|
void setVelocity(const osg::Vec3f& vel) { mParams.mVel = vel; }
|
||||||
void setVolume(float volume) { mParams.mVolume = volume; }
|
void setVolume(float volume) { mParams.mVolume = volume; }
|
||||||
void setBaseVolume(float volume) { mParams.mBaseVolume = volume; }
|
void setBaseVolume(float volume) { mParams.mBaseVolume = volume; }
|
||||||
void setFadeout(float duration) { setFade(duration, 0.0, Play_StopAtFadeEnd); }
|
void setFadeout(float duration) { setFade(duration, 0.0, Play_StopAtFadeEnd); }
|
||||||
|
@ -150,6 +154,8 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
const osg::Vec3f& getPosition() const { return mParams.mPos; }
|
const osg::Vec3f& getPosition() const { return mParams.mPos; }
|
||||||
|
const osg::Vec3f& getLastPosition() const { return mParams.mLastPos; }
|
||||||
|
const osg::Vec3f& getVelocity() const { return mParams.mVel; }
|
||||||
float getRealVolume() const { return mParams.mVolume * mParams.mBaseVolume * mParams.mFadeVolume; }
|
float getRealVolume() const { return mParams.mVolume * mParams.mBaseVolume * mParams.mFadeVolume; }
|
||||||
float getPitch() const { return mParams.mPitch; }
|
float getPitch() const { return mParams.mPitch; }
|
||||||
float getMinDistance() const { return mParams.mMinDistance; }
|
float getMinDistance() const { return mParams.mMinDistance; }
|
||||||
|
|
|
@ -119,6 +119,7 @@ namespace MWSound
|
||||||
, mListenerPos(0, 0, 0)
|
, mListenerPos(0, 0, 0)
|
||||||
, mListenerDir(1, 0, 0)
|
, mListenerDir(1, 0, 0)
|
||||||
, mListenerUp(0, 0, 1)
|
, mListenerUp(0, 0, 1)
|
||||||
|
, mListenerVel(0, 0, 0)
|
||||||
, mUnderwaterSound(nullptr)
|
, mUnderwaterSound(nullptr)
|
||||||
, mNearWaterSound(nullptr)
|
, mNearWaterSound(nullptr)
|
||||||
, mPlaybackPaused(false)
|
, mPlaybackPaused(false)
|
||||||
|
@ -960,7 +961,7 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
|
|
||||||
mOutput->startUpdate();
|
mOutput->startUpdate();
|
||||||
mOutput->updateListener(mListenerPos, mListenerDir, mListenerUp, env);
|
mOutput->updateListener(mListenerPos, mListenerDir, mListenerUp, mListenerVel, env);
|
||||||
|
|
||||||
updateMusic(duration);
|
updateMusic(duration);
|
||||||
|
|
||||||
|
@ -977,7 +978,13 @@ namespace MWSound
|
||||||
if (sound->getIs3D())
|
if (sound->getIs3D())
|
||||||
{
|
{
|
||||||
if (!ptr.isEmpty())
|
if (!ptr.isEmpty())
|
||||||
|
{
|
||||||
|
sound->setLastPosition(sound->getPosition());
|
||||||
sound->setPosition(ptr.getRefData().getPosition().asVec3());
|
sound->setPosition(ptr.getRefData().getPosition().asVec3());
|
||||||
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
sound->setVelocity(
|
||||||
|
(sound->getPosition() - sound->getLastPosition()) / world->getPhysicsFrameRateDt());
|
||||||
|
}
|
||||||
|
|
||||||
cull3DSound(sound);
|
cull3DSound(sound);
|
||||||
}
|
}
|
||||||
|
@ -1013,8 +1020,11 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
if (!ptr.isEmpty())
|
if (!ptr.isEmpty())
|
||||||
{
|
{
|
||||||
|
sound->setLastPosition(sound->getPosition());
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
sound->setPosition(world->getActorHeadTransform(ptr).getTrans());
|
sound->setPosition(world->getActorHeadTransform(ptr).getTrans());
|
||||||
|
sound->setVelocity(
|
||||||
|
(sound->getPosition() - sound->getLastPosition()) / world->getPhysicsFrameRateDt());
|
||||||
}
|
}
|
||||||
|
|
||||||
cull3DSound(sound);
|
cull3DSound(sound);
|
||||||
|
@ -1153,6 +1163,11 @@ namespace MWSound
|
||||||
mWaterSoundUpdater.setUnderwater(underwater);
|
mWaterSoundUpdater.setUnderwater(underwater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundManager::setListenerVel(const osg::Vec3f& vel)
|
||||||
|
{
|
||||||
|
mListenerVel = vel;
|
||||||
|
}
|
||||||
|
|
||||||
void SoundManager::updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated)
|
void SoundManager::updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated)
|
||||||
{
|
{
|
||||||
SoundMap::iterator snditer = mActiveSounds.find(old.mRef);
|
SoundMap::iterator snditer = mActiveSounds.find(old.mRef);
|
||||||
|
|
|
@ -92,6 +92,7 @@ namespace MWSound
|
||||||
osg::Vec3f mListenerPos;
|
osg::Vec3f mListenerPos;
|
||||||
osg::Vec3f mListenerDir;
|
osg::Vec3f mListenerDir;
|
||||||
osg::Vec3f mListenerUp;
|
osg::Vec3f mListenerUp;
|
||||||
|
osg::Vec3f mListenerVel;
|
||||||
|
|
||||||
int mPausedSoundTypes[BlockerType::MaxCount] = {};
|
int mPausedSoundTypes[BlockerType::MaxCount] = {};
|
||||||
|
|
||||||
|
@ -283,6 +284,8 @@ namespace MWSound
|
||||||
void setListenerPosDir(
|
void setListenerPosDir(
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater) override;
|
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater) override;
|
||||||
|
|
||||||
|
void setListenerVel(const osg::Vec3f& vel) override;
|
||||||
|
|
||||||
void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) override;
|
void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) override;
|
||||||
|
|
||||||
void clear() override;
|
void clear() override;
|
||||||
|
|
|
@ -61,8 +61,8 @@ namespace MWSound
|
||||||
virtual void startUpdate() = 0;
|
virtual void startUpdate() = 0;
|
||||||
virtual void finishUpdate() = 0;
|
virtual void finishUpdate() = 0;
|
||||||
|
|
||||||
virtual void updateListener(
|
virtual void updateListener(const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir,
|
||||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env)
|
const osg::Vec3f& vel, Environment env)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
virtual void pauseSounds(int types) = 0;
|
virtual void pauseSounds(int types) = 0;
|
||||||
|
|
|
@ -461,6 +461,11 @@ namespace MWWorld
|
||||||
|
|
||||||
update(magicBoltState, duration);
|
update(magicBoltState, duration);
|
||||||
|
|
||||||
|
for (const auto& sound : magicBoltState.mSounds)
|
||||||
|
{
|
||||||
|
sound->setVelocity(direction * speed);
|
||||||
|
}
|
||||||
|
|
||||||
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit
|
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit
|
||||||
// result.
|
// result.
|
||||||
std::vector<MWWorld::Ptr> targetActors;
|
std::vector<MWWorld::Ptr> targetActors;
|
||||||
|
|
|
@ -1460,6 +1460,8 @@ namespace MWWorld
|
||||||
void World::queueMovement(const Ptr& ptr, const osg::Vec3f& velocity)
|
void World::queueMovement(const Ptr& ptr, const osg::Vec3f& velocity)
|
||||||
{
|
{
|
||||||
mPhysics->queueObjectMovement(ptr, velocity);
|
mPhysics->queueObjectMovement(ptr, velocity);
|
||||||
|
if (ptr == MWMechanics::getPlayer())
|
||||||
|
MWBase::Environment::get().getSoundManager()->setListenerVel(velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::updateAnimatedCollisionShape(const Ptr& ptr)
|
void World::updateAnimatedCollisionShape(const Ptr& ptr)
|
||||||
|
@ -3182,6 +3184,11 @@ namespace MWWorld
|
||||||
return mWeatherManager->getSunPercentage(getTimeStamp().getHour());
|
return mWeatherManager->getSunPercentage(getTimeStamp().getHour());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float World::getPhysicsFrameRateDt() const
|
||||||
|
{
|
||||||
|
return mPhysics->mPhysicsDt;
|
||||||
|
}
|
||||||
|
|
||||||
bool World::findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result)
|
bool World::findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result)
|
||||||
{
|
{
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
|
|
|
@ -584,6 +584,8 @@ namespace MWWorld
|
||||||
float getSunVisibility() const override;
|
float getSunVisibility() const override;
|
||||||
float getSunPercentage() const override;
|
float getSunPercentage() const override;
|
||||||
|
|
||||||
|
float getPhysicsFrameRateDt() const override;
|
||||||
|
|
||||||
bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) override;
|
bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) override;
|
||||||
|
|
||||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Settings
|
||||||
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" };
|
SettingValue<bool> mCameraListener{ mIndex, "Sound", "camera listener" };
|
||||||
|
SettingValue<float> mDopplerFactor{ mIndex, "Sound", "doppler factor", makeClampSanitizerFloat(0, 1) };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,3 +121,13 @@ Sound Settings
|
||||||
When true, uses the camera position and direction for audio instead of the player position.
|
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.
|
This makes audio in third person sound relative to camera instead of the player.
|
||||||
False is vanilla Morrowind behaviour.
|
False is vanilla Morrowind behaviour.
|
||||||
|
|
||||||
|
.. omw-setting::
|
||||||
|
:title: doppler factor
|
||||||
|
:type: float32
|
||||||
|
:range: 0.0 (disabled), 1.0 (maximum strength)
|
||||||
|
:default: 0.25
|
||||||
|
:location: :bdg-success:`Launcher > Settings > Audio`
|
||||||
|
|
||||||
|
This setting controls the strength of the Doppler effect. The Doppler effect increases or decreases the pitch of sounds
|
||||||
|
relative to the velocity of the sound source and the listener.
|
||||||
|
|
|
@ -1451,5 +1451,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov
|
||||||
<source>Run Script After Startup:</source>
|
<source>Run Script After Startup:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source><html><head/><body><p>Controls the strength of the Doppler effect. Zero means it is completely disabled.</p><p>The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.</p></body></html></source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Doppler Factor</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -1451,5 +1451,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov
|
||||||
<source><html><head/><body><p>If enabled - makes transitions between different animations/poses much smoother. Also allows to load animation blending config YAML files that can be bundled with animations in order to customise blending styles.</p></body></html></source>
|
<source><html><head/><body><p>If enabled - makes transitions between different animations/poses much smoother. Also allows to load animation blending config YAML files that can be bundled with animations in order to customise blending styles.</p></body></html></source>
|
||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source><html><head/><body><p>Controls the strength of the Doppler effect. Zero means it is completely disabled.</p><p>The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.</p></body></html></source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Doppler Factor</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -1454,5 +1454,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov
|
||||||
<source>Run Script After Startup:</source>
|
<source>Run Script After Startup:</source>
|
||||||
<translation>Script à lancer après démarrage :</translation>
|
<translation>Script à lancer après démarrage :</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source><html><head/><body><p>Controls the strength of the Doppler effect. Zero means it is completely disabled.</p><p>The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.</p></body></html></source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Doppler Factor</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -1466,5 +1466,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov
|
||||||
<source>Use the Camera as the Sound Listener</source>
|
<source>Use the Camera as the Sound Listener</source>
|
||||||
<translation>Использовать камеру как слушателя</translation>
|
<translation>Использовать камеру как слушателя</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source><html><head/><body><p>Controls the strength of the Doppler effect. Zero means it is completely disabled.</p><p>The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.</p></body></html></source>
|
||||||
|
<translation><html><head/><body><p>Определяет силу эффекта Доплера. Нулевое значение означает, что эффект отключен полностью.</p><p>Эффект Доплера увеличивает или уменьшает высоту звуков в зависимости от скорости источника звука и слушателя.</p></body></html></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Doppler Factor</source>
|
||||||
|
<translation>Множитель эффекта Доплера</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -1470,5 +1470,13 @@ de ordinarie fonterna i Morrowind. Bocka denna ruta om du ändå föredrar ordin
|
||||||
<source><html><head/><body><p>If enabled - makes transitions between different animations/poses much smoother. Also allows to load animation blending config YAML files that can be bundled with animations in order to customise blending styles.</p></body></html></source>
|
<source><html><head/><body><p>If enabled - makes transitions between different animations/poses much smoother. Also allows to load animation blending config YAML files that can be bundled with animations in order to customise blending styles.</p></body></html></source>
|
||||||
<translation><html><head/><body><p>Vid aktivering gör denna funktion att övergångarna mellan olika animationer och poser blir mycket mjukare. Funktionen gör det också möjligt att konfigurera animationsövergångarna i YAML-filer. Dessa filer kan buntas ihop tillsammans med nya animationsfiler.</p></body></html></translation>
|
<translation><html><head/><body><p>Vid aktivering gör denna funktion att övergångarna mellan olika animationer och poser blir mycket mjukare. Funktionen gör det också möjligt att konfigurera animationsövergångarna i YAML-filer. Dessa filer kan buntas ihop tillsammans med nya animationsfiler.</p></body></html></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source><html><head/><body><p>Controls the strength of the Doppler effect. Zero means it is completely disabled.</p><p>The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.</p></body></html></source>
|
||||||
|
<translation><html><head/><body><p>Kontrollerar styrkan på dopplereffekten. Noll innebär helt inaktiverat.</p><p>Dopplereffekten höjer eller sänker tonhöjden på ljud i förhållande till ljudkällans hastighet och lyssnaren.</p></body></html></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Doppler Factor</source>
|
||||||
|
<translation>Dopplerfaktor</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -624,6 +624,9 @@ hrtf =
|
||||||
# Specifies whether to use camera as audio listener
|
# Specifies whether to use camera as audio listener
|
||||||
camera listener = false
|
camera listener = false
|
||||||
|
|
||||||
|
# Specifies strength of doppler effect
|
||||||
|
doppler factor = 0.25
|
||||||
|
|
||||||
[Video]
|
[Video]
|
||||||
|
|
||||||
# Resolution of the OpenMW window or screen.
|
# Resolution of the OpenMW window or screen.
|
||||||
|
|
Loading…
Reference in a new issue