forked from mirror/openmw-tes3mp
Implement water sounds (Closes #451)
This commit is contained in:
parent
be14ce414e
commit
c34d85ffc2
3 changed files with 116 additions and 3 deletions
|
@ -493,7 +493,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mEnvironment.setWindowManager (window);
|
mEnvironment.setWindowManager (window);
|
||||||
|
|
||||||
// Create sound system
|
// Create sound system
|
||||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mVFS.get(), mUseSound));
|
mEnvironment.setSoundManager (new MWSound::SoundManager(mVFS.get(), mFallbackMap, mUseSound));
|
||||||
|
|
||||||
if (!mSkipMenu)
|
if (!mSkipMenu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,8 +34,9 @@
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
SoundManager::SoundManager(const VFS::Manager* vfs, bool useSound)
|
SoundManager::SoundManager(const VFS::Manager* vfs, const std::map<std::string,std::string>& fallbackMap, bool useSound)
|
||||||
: mVFS(vfs)
|
: mVFS(vfs)
|
||||||
|
, mFallback(fallbackMap)
|
||||||
, mOutput(new DEFAULT_OUTPUT(*this))
|
, mOutput(new DEFAULT_OUTPUT(*this))
|
||||||
, mMasterVolume(1.0f)
|
, mMasterVolume(1.0f)
|
||||||
, mSFXVolume(1.0f)
|
, mSFXVolume(1.0f)
|
||||||
|
@ -61,6 +62,13 @@ namespace MWSound
|
||||||
mFootstepsVolume = Settings::Manager::getFloat("footsteps volume", "Sound");
|
mFootstepsVolume = Settings::Manager::getFloat("footsteps volume", "Sound");
|
||||||
mFootstepsVolume = std::min(std::max(mFootstepsVolume, 0.0f), 1.0f);
|
mFootstepsVolume = std::min(std::max(mFootstepsVolume, 0.0f), 1.0f);
|
||||||
|
|
||||||
|
mNearWaterRadius = mFallback.getFallbackInt("Water_NearWaterRadius");
|
||||||
|
mNearWaterPoints = mFallback.getFallbackInt("Water_NearWaterPoints");
|
||||||
|
mNearWaterIndoorTolerance = mFallback.getFallbackFloat("Water_NearWaterIndoorTolerance");
|
||||||
|
mNearWaterOutdoorTolerance = mFallback.getFallbackFloat("Water_NearWaterOutdoorTolerance");
|
||||||
|
mNearWaterIndoorID = mFallback.getFallbackString("Water_NearWaterIndoorID");
|
||||||
|
mNearWaterOutdoorID = mFallback.getFallbackString("Water_NearWaterOutdoorID");
|
||||||
|
|
||||||
mBufferCacheMin = std::max(Settings::Manager::getInt("buffer cache min", "Sound"), 1);
|
mBufferCacheMin = std::max(Settings::Manager::getInt("buffer cache min", "Sound"), 1);
|
||||||
mBufferCacheMax = std::max(Settings::Manager::getInt("buffer cache max", "Sound"), 1);
|
mBufferCacheMax = std::max(Settings::Manager::getInt("buffer cache max", "Sound"), 1);
|
||||||
mBufferCacheMax *= 1024*1024;
|
mBufferCacheMax *= 1024*1024;
|
||||||
|
@ -796,6 +804,96 @@ namespace MWSound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundManager::updateWaterSound(float /*duration*/)
|
||||||
|
{
|
||||||
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
const MWWorld::ConstPtr player = world->getPlayerPtr();
|
||||||
|
osg::Vec3f pos = player.getRefData().getPosition().asVec3();
|
||||||
|
|
||||||
|
float volume = 0.0f;
|
||||||
|
const std::string& soundId = player.getCell()->isExterior() ? mNearWaterOutdoorID : mNearWaterIndoorID;
|
||||||
|
|
||||||
|
if (!mListenerUnderwater)
|
||||||
|
{
|
||||||
|
if (player.getCell()->getCell()->hasWater())
|
||||||
|
{
|
||||||
|
float dist = std::abs(player.getCell()->getWaterLevel() - pos.z());
|
||||||
|
|
||||||
|
if (player.getCell()->isExterior() && dist < mNearWaterOutdoorTolerance)
|
||||||
|
{
|
||||||
|
volume = (mNearWaterOutdoorTolerance - dist) / mNearWaterOutdoorTolerance;
|
||||||
|
|
||||||
|
if (mNearWaterPoints > 1)
|
||||||
|
{
|
||||||
|
int underwaterPoints = 0;
|
||||||
|
|
||||||
|
float step = mNearWaterRadius * 2.0f / (mNearWaterPoints - 1);
|
||||||
|
|
||||||
|
for (int x = 0; x < mNearWaterPoints; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < mNearWaterPoints; y++)
|
||||||
|
{
|
||||||
|
float height = world->getTerrainHeightAt(
|
||||||
|
osg::Vec3f(pos.x() - mNearWaterRadius + x*step, pos.y() - mNearWaterRadius + y*step, 0.0f));
|
||||||
|
|
||||||
|
if (height < 0)
|
||||||
|
underwaterPoints++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
volume *= underwaterPoints * 2.0f / (mNearWaterPoints*mNearWaterPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!player.getCell()->isExterior() && dist < mNearWaterIndoorTolerance)
|
||||||
|
{
|
||||||
|
volume = (mNearWaterIndoorTolerance - dist) / mNearWaterIndoorTolerance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
volume = 1.0f;
|
||||||
|
|
||||||
|
volume = std::min(volume, 1.0f);
|
||||||
|
|
||||||
|
if (mNearWaterSound)
|
||||||
|
{
|
||||||
|
if (volume == 0.0f)
|
||||||
|
{
|
||||||
|
mOutput->finishSound(mNearWaterSound);
|
||||||
|
mNearWaterSound.reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool soundIdChanged = false;
|
||||||
|
|
||||||
|
Sound_Buffer* sfx = lookupSound(Misc::StringUtils::lowerCase(soundId));
|
||||||
|
|
||||||
|
for (SoundMap::const_iterator snditer = mActiveSounds.begin(); snditer != mActiveSounds.end(); ++snditer)
|
||||||
|
{
|
||||||
|
for (SoundBufferRefPairList::const_iterator pairiter = snditer->second.begin(); pairiter != snditer->second.end(); ++pairiter)
|
||||||
|
{
|
||||||
|
if (pairiter->first == mNearWaterSound)
|
||||||
|
{
|
||||||
|
if (pairiter->second != sfx)
|
||||||
|
soundIdChanged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (soundIdChanged)
|
||||||
|
{
|
||||||
|
mOutput->finishSound(mNearWaterSound);
|
||||||
|
mNearWaterSound = playSound(soundId, volume, 1.0f, Play_TypeSfx, Play_Loop);
|
||||||
|
}
|
||||||
|
else if (sfx)
|
||||||
|
mNearWaterSound->setVolume(volume * sfx->mVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (volume > 0.0f)
|
||||||
|
mNearWaterSound = playSound(soundId, volume, 1.0f, Play_TypeSfx, Play_Loop);
|
||||||
|
}
|
||||||
|
|
||||||
void SoundManager::updateSounds(float duration)
|
void SoundManager::updateSounds(float duration)
|
||||||
{
|
{
|
||||||
static float timePassed = 0.0;
|
static float timePassed = 0.0;
|
||||||
|
@ -941,6 +1039,7 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
updateSounds(duration);
|
updateSounds(duration);
|
||||||
updateRegionSound(duration);
|
updateRegionSound(duration);
|
||||||
|
updateWaterSound(duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1105,6 +1204,7 @@ namespace MWSound
|
||||||
mOutput->finishStream(*trkiter);
|
mOutput->finishStream(*trkiter);
|
||||||
mActiveTracks.clear();
|
mActiveTracks.clear();
|
||||||
mUnderwaterSound.reset();
|
mUnderwaterSound.reset();
|
||||||
|
mNearWaterSound.reset();
|
||||||
stopMusic();
|
stopMusic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
#include <components/fallback/fallback.hpp>
|
||||||
|
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
||||||
namespace VFS
|
namespace VFS
|
||||||
|
@ -44,6 +46,8 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
const VFS::Manager* mVFS;
|
const VFS::Manager* mVFS;
|
||||||
|
|
||||||
|
Fallback::Map mFallback;
|
||||||
|
|
||||||
std::auto_ptr<Sound_Output> mOutput;
|
std::auto_ptr<Sound_Output> mOutput;
|
||||||
|
|
||||||
// Caches available music tracks by <playlist name, (sound files) >
|
// Caches available music tracks by <playlist name, (sound files) >
|
||||||
|
@ -56,6 +60,13 @@ namespace MWSound
|
||||||
float mVoiceVolume;
|
float mVoiceVolume;
|
||||||
float mFootstepsVolume;
|
float mFootstepsVolume;
|
||||||
|
|
||||||
|
int mNearWaterRadius;
|
||||||
|
int mNearWaterPoints;
|
||||||
|
float mNearWaterIndoorTolerance;
|
||||||
|
float mNearWaterOutdoorTolerance;
|
||||||
|
std::string mNearWaterIndoorID;
|
||||||
|
std::string mNearWaterOutdoorID;
|
||||||
|
|
||||||
typedef std::auto_ptr<std::deque<Sound_Buffer> > SoundBufferList;
|
typedef std::auto_ptr<std::deque<Sound_Buffer> > SoundBufferList;
|
||||||
// List of sound buffers, grown as needed. New enties are added to the
|
// List of sound buffers, grown as needed. New enties are added to the
|
||||||
// back, allowing existing Sound_Buffer references/pointers to remain
|
// back, allowing existing Sound_Buffer references/pointers to remain
|
||||||
|
@ -94,6 +105,7 @@ namespace MWSound
|
||||||
int mPausedSoundTypes;
|
int mPausedSoundTypes;
|
||||||
|
|
||||||
MWBase::SoundPtr mUnderwaterSound;
|
MWBase::SoundPtr mUnderwaterSound;
|
||||||
|
MWBase::SoundPtr mNearWaterSound;
|
||||||
|
|
||||||
Sound_Buffer *insertSound(const std::string &soundId, const ESM::Sound *sound);
|
Sound_Buffer *insertSound(const std::string &soundId, const ESM::Sound *sound);
|
||||||
|
|
||||||
|
@ -108,6 +120,7 @@ namespace MWSound
|
||||||
void streamMusicFull(const std::string& filename);
|
void streamMusicFull(const std::string& filename);
|
||||||
void updateSounds(float duration);
|
void updateSounds(float duration);
|
||||||
void updateRegionSound(float duration);
|
void updateRegionSound(float duration);
|
||||||
|
void updateWaterSound(float duration);
|
||||||
|
|
||||||
float volumeFromType(PlayType type) const;
|
float volumeFromType(PlayType type) const;
|
||||||
|
|
||||||
|
@ -119,7 +132,7 @@ namespace MWSound
|
||||||
friend class OpenAL_Output;
|
friend class OpenAL_Output;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SoundManager(const VFS::Manager* vfs, bool useSound);
|
SoundManager(const VFS::Manager* vfs, const std::map<std::string, std::string>& fallbackMap, bool useSound);
|
||||||
virtual ~SoundManager();
|
virtual ~SoundManager();
|
||||||
|
|
||||||
virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
|
virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
|
||||||
|
|
Loading…
Reference in a new issue