forked from teamnwah/openmw-tes3coop
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
0522da257c
9 changed files with 74 additions and 36 deletions
|
@ -42,15 +42,21 @@ namespace MWBase
|
|||
Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position
|
||||
* but do not keep it updated (the sound will not move with
|
||||
* the object and will not stop when the object is deleted. */
|
||||
|
||||
Play_LoopNoEnv = Play_Loop | Play_NoEnv
|
||||
Play_RemoveAtDistance = 1<<3, /* (3D only) If the listener gets further than 2000 units away
|
||||
from the sound source, the sound is removed.
|
||||
This is weird stuff but apparently how vanilla works for sounds
|
||||
played by the PlayLoopSound family of script functions. Perhaps we
|
||||
can make this cut off a more subtle fade later, but have to
|
||||
be careful to not change the overall volume of areas by too much. */
|
||||
Play_LoopNoEnv = Play_Loop | Play_NoEnv,
|
||||
Play_LoopRemoveAtDistance = Play_Loop | Play_RemoveAtDistance
|
||||
};
|
||||
enum PlayType {
|
||||
Play_TypeSfx = 1<<3, /* Normal SFX sound */
|
||||
Play_TypeVoice = 1<<4, /* Voice sound */
|
||||
Play_TypeFoot = 1<<5, /* Footstep sound */
|
||||
Play_TypeMusic = 1<<6, /* Music track */
|
||||
Play_TypeMovie = 1<<7, /* Movie audio track */
|
||||
Play_TypeSfx = 1<<4, /* Normal SFX sound */
|
||||
Play_TypeVoice = 1<<5, /* Voice sound */
|
||||
Play_TypeFoot = 1<<6, /* Footstep sound */
|
||||
Play_TypeMusic = 1<<7, /* Music track */
|
||||
Play_TypeMovie = 1<<8, /* Movie audio track */
|
||||
Play_TypeMask = Play_TypeSfx|Play_TypeVoice|Play_TypeFoot|Play_TypeMusic|Play_TypeMovie
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/refdata.hpp"
|
||||
|
@ -120,15 +119,6 @@ namespace MWRender
|
|||
setPosition(Ogre::Vector3(x,y,z));
|
||||
}
|
||||
|
||||
void Camera::updateListener()
|
||||
{
|
||||
Ogre::Vector3 pos = mCamera->getRealPosition();
|
||||
Ogre::Vector3 dir = mCamera->getRealDirection();
|
||||
Ogre::Vector3 up = mCamera->getRealUp();
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up);
|
||||
}
|
||||
|
||||
void Camera::update(float duration, bool paused)
|
||||
{
|
||||
if (mAnimation->upperBodyReady())
|
||||
|
@ -148,7 +138,6 @@ namespace MWRender
|
|||
}
|
||||
}
|
||||
|
||||
updateListener();
|
||||
if (paused)
|
||||
return;
|
||||
|
||||
|
|
|
@ -50,9 +50,6 @@ namespace MWRender
|
|||
bool mVanityToggleQueued;
|
||||
bool mViewModeToggleQueued;
|
||||
|
||||
/// Updates sound manager listener data
|
||||
void updateListener();
|
||||
|
||||
void setPosition(const Ogre::Vector3& position);
|
||||
void setPosition(float x, float y, float z);
|
||||
|
||||
|
|
|
@ -121,8 +121,8 @@ namespace MWScript
|
|||
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, 1.0, 1.0,
|
||||
MWBase::SoundManager::Play_TypeSfx,
|
||||
mLoop ? MWBase::SoundManager::Play_Loop :
|
||||
MWBase::SoundManager::Play_Normal);
|
||||
mLoop ? MWBase::SoundManager::Play_LoopRemoveAtDistance
|
||||
: MWBase::SoundManager::Play_Normal);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -150,8 +150,8 @@ namespace MWScript
|
|||
|
||||
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, volume, pitch,
|
||||
MWBase::SoundManager::Play_TypeSfx,
|
||||
mLoop ? MWBase::SoundManager::Play_Loop :
|
||||
MWBase::SoundManager::Play_Normal);
|
||||
mLoop ? MWBase::SoundManager::Play_LoopRemoveAtDistance
|
||||
: MWBase::SoundManager::Play_Normal);
|
||||
|
||||
}
|
||||
};
|
||||
|
|
|
@ -696,7 +696,7 @@ void OpenAL_Output::init(const std::string &devname)
|
|||
fail(std::string("Failed to setup context: ")+alcGetString(mDevice, alcGetError(mDevice)));
|
||||
}
|
||||
|
||||
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
throwALerror();
|
||||
|
||||
ALCint maxmono=0, maxstereo=0;
|
||||
|
|
|
@ -103,24 +103,31 @@ namespace MWSound
|
|||
std::string SoundManager::lookup(const std::string &soundId,
|
||||
float &volume, float &min, float &max)
|
||||
{
|
||||
const ESM::Sound *snd =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Sound>().find(soundId);
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
const ESM::Sound *snd = world->getStore().get<ESM::Sound>().find(soundId);
|
||||
|
||||
volume *= pow(10.0, (snd->mData.mVolume/255.0*3348.0 - 3348.0) / 2000.0);
|
||||
|
||||
if(snd->mData.mMinRange == 0 && snd->mData.mMaxRange == 0)
|
||||
{
|
||||
min = 100.0f;
|
||||
max = 2000.0f;
|
||||
static const float fAudioDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMinDistance")->getFloat();
|
||||
static const float fAudioDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMaxDistance")->getFloat();
|
||||
min = fAudioDefaultMinDistance;
|
||||
max = fAudioDefaultMaxDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
min = snd->mData.mMinRange * 20.0f;
|
||||
max = snd->mData.mMaxRange * 50.0f;
|
||||
min = std::max(min, 1.0f);
|
||||
max = std::max(min, max);
|
||||
min = snd->mData.mMinRange;
|
||||
max = snd->mData.mMaxRange;
|
||||
}
|
||||
|
||||
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
|
||||
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->getFloat();
|
||||
min *= fAudioMinDistanceMult;
|
||||
max *= fAudioMaxDistanceMult;
|
||||
min = std::max(min, 1.0f);
|
||||
max = std::max(min, max);
|
||||
|
||||
return "Sound/"+snd->mSound;
|
||||
}
|
||||
|
||||
|
@ -250,8 +257,19 @@ namespace MWSound
|
|||
const ESM::Position &pos = ptr.getRefData().getPosition();
|
||||
const Ogre::Vector3 objpos(pos.pos);
|
||||
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
|
||||
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->getFloat();
|
||||
static const float fAudioVoiceDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioVoiceDefaultMinDistance")->getFloat();
|
||||
static const float fAudioVoiceDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioVoiceDefaultMaxDistance")->getFloat();
|
||||
|
||||
float minDistance = fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult;
|
||||
float maxDistance = fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult;
|
||||
minDistance = std::max(minDistance, 1.f);
|
||||
maxDistance = std::max(minDistance, maxDistance);
|
||||
|
||||
MWBase::SoundPtr sound = mOutput->playSound3D(filePath, objpos, 1.0f, basevol, 1.0f,
|
||||
20.0f, 1500.0f, Play_Normal|Play_TypeVoice, 0, true);
|
||||
minDistance, maxDistance, Play_Normal|Play_TypeVoice, 0, true);
|
||||
mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound"));
|
||||
}
|
||||
catch(std::exception &e)
|
||||
|
@ -367,6 +385,11 @@ namespace MWSound
|
|||
const ESM::Position &pos = ptr.getRefData().getPosition();
|
||||
const Ogre::Vector3 objpos(pos.pos);
|
||||
|
||||
if ((mode & Play_RemoveAtDistance) && mListenerPos.squaredDistance(objpos) > 2000*2000)
|
||||
{
|
||||
return MWBase::SoundPtr();
|
||||
}
|
||||
|
||||
sound = mOutput->playSound3D(file, objpos, volume, basevol, pitch, min, max, mode|type, offset);
|
||||
if((mode&Play_NoTrack))
|
||||
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId);
|
||||
|
@ -632,6 +655,13 @@ namespace MWSound
|
|||
const ESM::Position &pos = ptr.getRefData().getPosition();
|
||||
const Ogre::Vector3 objpos(pos.pos);
|
||||
snditer->first->setPosition(objpos);
|
||||
|
||||
if ((snditer->first->mFlags & Play_RemoveAtDistance)
|
||||
&& mListenerPos.squaredDistance(Ogre::Vector3(ptr.getRefData().getPosition().pos)) > 2000*2000)
|
||||
{
|
||||
mActiveSounds.erase(snditer++);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//update fade out
|
||||
if(snditer->first->mFadeOutTime>0)
|
||||
|
|
|
@ -27,7 +27,9 @@ namespace MWWorld
|
|||
LiveRef *find (const std::string& name)
|
||||
{
|
||||
for (typename List::iterator iter (mList.begin()); iter!=mList.end(); ++iter)
|
||||
if (iter->mRef.getRefId() == name)
|
||||
if (!iter->mData.isDeletedByContentFile()
|
||||
&& (iter->mRef.getRefNum().mContentFile != -1 || iter->mData.getCount() > 0)
|
||||
&& iter->mRef.getRefId() == name)
|
||||
return &*iter;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1560,6 +1560,8 @@ namespace MWWorld
|
|||
|
||||
updateWindowManager ();
|
||||
|
||||
updateSoundListener();
|
||||
|
||||
if (!paused && mPlayer->getPlayer().getCell()->isExterior())
|
||||
{
|
||||
ESM::Position pos = mPlayer->getPlayer().getRefData().getPosition();
|
||||
|
@ -1567,6 +1569,17 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
void World::updateSoundListener()
|
||||
{
|
||||
Ogre::Vector3 playerPos = mPlayer->getPlayer().getRefData().getBaseNode()->getPosition();
|
||||
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(getPlayerPtr().getRefData().getHandle());
|
||||
if(actor) playerPos.z += 1.85*actor->getHalfExtents().z;
|
||||
Ogre::Quaternion playerOrient = Ogre::Quaternion(Ogre::Radian(getPlayerPtr().getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
|
||||
Ogre::Quaternion(Ogre::Radian(getPlayerPtr().getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X);
|
||||
MWBase::Environment::get().getSoundManager()->setListenerPosDir(playerPos, playerOrient.yAxis(),
|
||||
playerOrient.zAxis());
|
||||
}
|
||||
|
||||
void World::updateWindowManager ()
|
||||
{
|
||||
// inform the GUI about focused object
|
||||
|
|
|
@ -109,6 +109,7 @@ namespace MWWorld
|
|||
|
||||
Ptr copyObjectToCell(const Ptr &ptr, CellStore* cell, ESM::Position pos, bool adjustPos=true);
|
||||
|
||||
void updateSoundListener();
|
||||
void updateWindowManager ();
|
||||
void performUpdateSceneQueries ();
|
||||
void getFacedHandle(std::string& facedHandle, float maxDistance, bool ignorePlayer=true);
|
||||
|
|
Loading…
Reference in a new issue