From 8a8b4986da14c5b80d5d5ecebbb8ef2718c3f0c1 Mon Sep 17 00:00:00 2001 From: Giovanni Bodega Date: Wed, 6 May 2020 16:39:32 +0100 Subject: [PATCH 01/33] Fixed passed indexes for object deletion #5384 --- apps/opencs/model/world/idtable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index a0dbd7bad..8ae2fce54 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -94,7 +94,7 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value // views that the whole row has changed. emit dataChanged(this->index(index.row(), 0), - this->index(index.row(), columnCount(index.parent()))); + this->index(index.row(), columnCount(index.parent()) - 1)); } else { From 411b6dcd8e581a58106b16e12c2b8e4dcae7a796 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Mon, 18 May 2020 14:46:20 +0300 Subject: [PATCH 02/33] Don't clear spells for a dead player, preventing resurrection problems --- apps/openmw/mwmechanics/actors.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 223d9fc34..55f8feb87 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1865,13 +1865,17 @@ namespace MWMechanics } else if (killResult == CharacterController::Result_DeathAnimJustFinished) { + bool isPlayer = iter->first == getPlayer(); notifyDied(iter->first); // Reset magic effects and recalculate derived effects // One case where we need this is to make sure bound items are removed upon death stats.modifyMagicEffects(MWMechanics::MagicEffects()); stats.getActiveSpells().clear(); - stats.getSpells().clear(); + + if (!isPlayer) + stats.getSpells().clear(); + // Make sure spell effects are removed purgeSpellEffects(stats.getActorId()); @@ -1880,7 +1884,7 @@ namespace MWMechanics if (iter->first.getClass().isNpc()) calculateNpcStatModifiers(iter->first, 0); - if( iter->first == getPlayer()) + if (isPlayer) { //player's death animation is over MWBase::Environment::get().getStateManager()->askLoadRecent(); From f53f049a648f1ffbc61558e2369080dc2ead06db Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Wed, 1 Jul 2020 17:42:18 +0200 Subject: [PATCH 03/33] give MacOS 10.15 a spin --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d877e8acc..5fec5a830 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,9 +37,9 @@ addons: build_command: "make VERBOSE=1 -j3" matrix: include: - - name: OpenMW (all) on macOS Xcode 10.2 + - name: OpenMW (all) on MacOS 10.15 with Xcode 12 os: osx - osx_image: xcode10.2 + osx_image: xcode12 if: branch != coverity_scan - name: OpenMW (all) on Ubuntu Focal with GCC os: linux From 3eeee4bc9477451c0ec01377b3d96e73c59e17ef Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Wed, 1 Jul 2020 17:52:34 +0200 Subject: [PATCH 04/33] drop need to upgrade qt, 5.15 is by default installed; add CXX_FLAGS; retarget SYSROOT to 10.15 --- CI/before_install.osx.sh | 1 - CI/before_script.osx.sh | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index e279d1933..0f69ecb39 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -2,7 +2,6 @@ brew update brew outdated pkgconfig || brew upgrade pkgconfig -brew install qt brew install ccache curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 01d9d2b80..c71dc3d6f 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -13,8 +13,9 @@ cmake \ -D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH" \ -D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \ -D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \ +-D CMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.9" \ --D CMAKE_OSX_SYSROOT="macosx10.14" \ +-D CMAKE_OSX_SYSROOT="macosx10.15" \ -D CMAKE_BUILD_TYPE=Release \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D BUILD_ESMTOOL=FALSE \ From a62e3a7b35c46c4177625a20c392605a08fca536 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Wed, 1 Jul 2020 18:50:41 +0200 Subject: [PATCH 05/33] What happens when I remove the sysroot line? --- CI/before_script.osx.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index c71dc3d6f..8bcfe99ce 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -15,7 +15,6 @@ cmake \ -D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \ -D CMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.9" \ --D CMAKE_OSX_SYSROOT="macosx10.15" \ -D CMAKE_BUILD_TYPE=Release \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D BUILD_ESMTOOL=FALSE \ From 1e23d007dd8b16905d5efb1bd4d2c15480deadbb Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Wed, 1 Jul 2020 22:23:02 +0200 Subject: [PATCH 06/33] Use Debug instead of Release to increase build time (passing -O0) --- CI/before_script.osx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 8bcfe99ce..7ba21b23b 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -15,7 +15,7 @@ cmake \ -D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \ -D CMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.9" \ --D CMAKE_BUILD_TYPE=Release \ +-D CMAKE_BUILD_TYPE=DEBUG \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D BUILD_ESMTOOL=FALSE \ -G"Unix Makefiles" \ From 3ea576efdc014e89258b77d3d1037f8f18297f51 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Fri, 3 Jul 2020 23:24:54 +0200 Subject: [PATCH 07/33] do not build a few things; temporary disable checking package; get things compiling and cached first --- .travis.yml | 2 +- CI/before_install.osx.sh | 2 -- CI/before_script.osx.sh | 3 +++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5fec5a830..cfc449434 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,7 +72,7 @@ script: - cd ./build - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ${ANALYZE} make -j3; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi +# - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi - cd "${TRAVIS_BUILD_DIR}" diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index 0f69ecb39..5dae1f102 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -1,7 +1,5 @@ #!/bin/sh -e -brew update -brew outdated pkgconfig || brew upgrade pkgconfig brew install ccache curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 7ba21b23b..7438c6c7a 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -18,5 +18,8 @@ cmake \ -D CMAKE_BUILD_TYPE=DEBUG \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D BUILD_ESMTOOL=FALSE \ +-D BUILD_BSATOOL=FALSE \ +-D BUILD_ESSIMPORTER=FALSE \ +-D BUILD_NIFTEST=FALSE \ -G"Unix Makefiles" \ .. From 6ca29c610740b9ab4c1fd96720de95c1919447c2 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 28 Jun 2020 17:17:43 +0200 Subject: [PATCH 08/33] Use common type for pool of sounds and streams --- apps/openmw/mwsound/soundmanagerimp.cpp | 58 ++++++++----------------- apps/openmw/mwsound/soundmanagerimp.hpp | 8 ++-- components/misc/objectpool.hpp | 46 ++++++++++++++++++++ 3 files changed, 66 insertions(+), 46 deletions(-) create mode 100644 components/misc/objectpool.hpp diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 3f21487bc..71ed96ac9 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -58,8 +58,6 @@ namespace MWSound , mWaterSoundUpdater(makeWaterSoundUpdaterSettings()) , mSoundBuffers(new SoundBufferList::element_type()) , mBufferCacheSize(0) - , mSounds(new std::deque()) - , mStreams(new std::deque()) , mMusic(nullptr) , mListenerUnderwater(false) , mListenerPos(0,0,0) @@ -270,34 +268,12 @@ namespace MWSound Sound *SoundManager::getSoundRef() { - Sound *ret; - if(!mUnusedSounds.empty()) - { - ret = mUnusedSounds.back(); - mUnusedSounds.pop_back(); - } - else - { - mSounds->emplace_back(); - ret = &mSounds->back(); - } - return ret; + return mSounds.get(); } Stream *SoundManager::getStreamRef() { - Stream *ret; - if(!mUnusedStreams.empty()) - { - ret = mUnusedStreams.back(); - mUnusedStreams.pop_back(); - } - else - { - mStreams->emplace_back(); - ret = &mStreams->back(); - } - return ret; + return mStreams.get(); } Stream *SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal) @@ -326,7 +302,7 @@ namespace MWSound } if(!played) { - mUnusedStreams.push_back(sound); + mStreams.recycle(sound); return nullptr; } return sound; @@ -343,7 +319,7 @@ namespace MWSound if(mMusic) { mOutput->finishStream(mMusic); - mUnusedStreams.push_back(mMusic); + mStreams.recycle(mMusic); mMusic = nullptr; } } @@ -572,7 +548,7 @@ namespace MWSound if(snditer != mSaySoundsQueue.end()) { mOutput->finishStream(snditer->second); - mUnusedStreams.push_back(snditer->second); + mStreams.recycle(snditer->second); mSaySoundsQueue.erase(snditer); } @@ -580,7 +556,7 @@ namespace MWSound if(snditer != mActiveSaySounds.end()) { mOutput->finishStream(snditer->second); - mUnusedStreams.push_back(snditer->second); + mStreams.recycle(snditer->second); mActiveSaySounds.erase(snditer); } } @@ -595,7 +571,7 @@ namespace MWSound track->init(1.0f, volumeFromType(type), 1.0f, PlayMode::NoEnv|type|Play_2D); if(!mOutput->streamSound(decoder, track)) { - mUnusedStreams.push_back(track); + mStreams.recycle(track); return nullptr; } @@ -611,7 +587,7 @@ namespace MWSound TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream); if(iter != mActiveTracks.end() && *iter == stream) mActiveTracks.erase(iter); - mUnusedStreams.push_back(stream); + mStreams.recycle(stream); } double SoundManager::getTrackTimeDelay(Stream *stream) @@ -635,7 +611,7 @@ namespace MWSound sound->init(volume * sfx->mVolume, volumeFromType(type), pitch, mode|type|Play_2D); if(!mOutput->playSound(sound, sfx->mHandle, offset)) { - mUnusedSounds.push_back(sound); + mSounds.recycle(sound); return nullptr; } @@ -682,7 +658,7 @@ namespace MWSound } if(!played) { - mUnusedSounds.push_back(sound); + mSounds.recycle(sound); return nullptr; } @@ -712,7 +688,7 @@ namespace MWSound sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D); if(!mOutput->playSound3D(sound, sfx->mHandle, offset)) { - mUnusedSounds.push_back(sound); + mSounds.recycle(sound); return nullptr; } @@ -1023,7 +999,7 @@ namespace MWSound if(!mOutput->isSoundPlaying(sound)) { mOutput->finishSound(sound); - mUnusedSounds.push_back(sound); + mSounds.recycle(sound); if(sound == mUnderwaterSound) mUnderwaterSound = nullptr; if(sound == mNearWaterSound) @@ -1067,7 +1043,7 @@ namespace MWSound if(!mOutput->isStreamPlaying(sound)) { mOutput->finishStream(sound); - mUnusedStreams.push_back(sound); + mStreams.recycle(sound); mActiveSaySounds.erase(sayiter++); } else @@ -1292,7 +1268,7 @@ namespace MWSound for(SoundBufferRefPair &sndbuf : snd.second) { mOutput->finishSound(sndbuf.first); - mUnusedSounds.push_back(sndbuf.first); + mSounds.recycle(sndbuf.first); Sound_Buffer *sfx = sndbuf.second; if(sfx->mUses-- == 1) mUnusedBuffers.push_front(sfx); @@ -1305,21 +1281,21 @@ namespace MWSound for(SaySoundMap::value_type &snd : mSaySoundsQueue) { mOutput->finishStream(snd.second); - mUnusedStreams.push_back(snd.second); + mStreams.recycle(snd.second); } mSaySoundsQueue.clear(); for(SaySoundMap::value_type &snd : mActiveSaySounds) { mOutput->finishStream(snd.second); - mUnusedStreams.push_back(snd.second); + mStreams.recycle(snd.second); } mActiveSaySounds.clear(); for(Stream *sound : mActiveTracks) { mOutput->finishStream(sound); - mUnusedStreams.push_back(sound); + mStreams.recycle(sound); } mActiveTracks.clear(); mPlaybackPaused = false; diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index 90bf4b12c..e03bd7b1f 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -9,7 +9,7 @@ #include #include - +#include #include #include "../mwbase/soundmanager.hpp" @@ -79,11 +79,9 @@ namespace MWSound typedef std::deque SoundList; SoundList mUnusedBuffers; - std::unique_ptr> mSounds; - std::vector mUnusedSounds; + Misc::ObjectPool mSounds; - std::unique_ptr> mStreams; - std::vector mUnusedStreams; + Misc::ObjectPool mStreams; typedef std::pair SoundBufferRefPair; typedef std::vector SoundBufferRefPairList; diff --git a/components/misc/objectpool.hpp b/components/misc/objectpool.hpp new file mode 100644 index 000000000..97a055331 --- /dev/null +++ b/components/misc/objectpool.hpp @@ -0,0 +1,46 @@ +#ifndef OPENMW_COMPONENTS_MISC_OBJECTPOOL_H +#define OPENMW_COMPONENTS_MISC_OBJECTPOOL_H + +#include +#include +#include + +namespace Misc +{ + template + class ObjectPool + { + public: + ObjectPool() + : mObjects(std::make_unique>()) {} + + T* get() + { + T* object; + + if (!mUnused.empty()) + { + object = mUnused.back(); + mUnused.pop_back(); + } + else + { + mObjects->emplace_back(); + object = &mObjects->back(); + } + + return object; + } + + void recycle(T* object) + { + mUnused.push_back(object); + } + + private: + std::unique_ptr> mObjects; + std::vector mUnused; + }; +} + +#endif From 02f9b44f01b8ab052b9381b1757ce818d7052277 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 28 Jun 2020 18:25:23 +0200 Subject: [PATCH 09/33] Use RAII for object ptr from pool --- apps/openmw/mwsound/soundmanagerimp.cpp | 187 ++++++++++-------------- apps/openmw/mwsound/soundmanagerimp.hpp | 17 ++- components/misc/objectpool.hpp | 49 ++++++- 3 files changed, 134 insertions(+), 119 deletions(-) diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 71ed96ac9..eed935e61 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -58,7 +58,6 @@ namespace MWSound , mWaterSoundUpdater(makeWaterSoundUpdaterSettings()) , mSoundBuffers(new SoundBufferList::element_type()) , mBufferCacheSize(0) - , mMusic(nullptr) , mListenerUnderwater(false) , mListenerPos(0,0,0) , mListenerDir(1,0,0) @@ -266,17 +265,17 @@ namespace MWSound return nullptr; } - Sound *SoundManager::getSoundRef() + SoundPtr SoundManager::getSoundRef() { return mSounds.get(); } - Stream *SoundManager::getStreamRef() + StreamPtr SoundManager::getStreamRef() { return mStreams.get(); } - Stream *SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal) + StreamPtr SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal) { MWBase::World* world = MWBase::Environment::get().getWorld(); static const float fAudioMinDistanceMult = world->getStore().get().find("fAudioMinDistanceMult")->mValue.getFloat(); @@ -288,23 +287,20 @@ namespace MWSound bool played; float basevol = volumeFromType(Type::Voice); - Stream *sound = getStreamRef(); + StreamPtr sound = getStreamRef(); if(playlocal) { sound->init(1.0f, basevol, 1.0f, PlayMode::NoEnv|Type::Voice|Play_2D); - played = mOutput->streamSound(decoder, sound, true); + played = mOutput->streamSound(decoder, sound.get(), true); } else { sound->init(pos, 1.0f, basevol, 1.0f, minDistance, maxDistance, PlayMode::Normal|Type::Voice|Play_3D); - played = mOutput->streamSound3D(decoder, sound, true); + played = mOutput->streamSound3D(decoder, sound.get(), true); } if(!played) - { - mStreams.recycle(sound); return nullptr; - } return sound; } @@ -318,8 +314,7 @@ namespace MWSound { if(mMusic) { - mOutput->finishStream(mMusic); - mStreams.recycle(mMusic); + mOutput->finishStream(mMusic.get()); mMusic = nullptr; } } @@ -339,7 +334,7 @@ namespace MWSound mMusic = getStreamRef(); mMusic->init(1.0f, volumeFromType(Type::Music), 1.0f, PlayMode::NoEnv|Type::Music|Play_2D); - mOutput->streamSound(decoder, mMusic); + mOutput->streamSound(decoder, mMusic.get()); } void SoundManager::advanceMusic(const std::string& filename) @@ -389,7 +384,7 @@ namespace MWSound bool SoundManager::isMusicPlaying() { - return mMusic && mOutput->isStreamPlaying(mMusic); + return mMusic && mOutput->isStreamPlaying(mMusic.get()); } void SoundManager::playPlaylist(const std::string &playlist) @@ -472,10 +467,10 @@ namespace MWSound const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans(); stopSay(ptr); - Stream *sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); + StreamPtr sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); if(!sound) return; - mSaySoundsQueue.emplace(ptr, sound); + mSaySoundsQueue.emplace(ptr, std::move(sound)); } float SoundManager::getSaySoundLoudness(const MWWorld::ConstPtr &ptr) const @@ -483,7 +478,7 @@ namespace MWSound SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr); if(snditer != mActiveSaySounds.end()) { - Stream *sound = snditer->second; + Stream *sound = snditer->second.get(); return mOutput->getStreamLoudness(sound); } @@ -503,10 +498,10 @@ namespace MWSound return; stopSay(MWWorld::ConstPtr()); - Stream *sound = playVoice(decoder, osg::Vec3f(), true); + StreamPtr sound = playVoice(decoder, osg::Vec3f(), true); if(!sound) return; - mActiveSaySounds.insert(std::make_pair(MWWorld::ConstPtr(), sound)); + mActiveSaySounds.emplace(MWWorld::ConstPtr(), std::move(sound)); } bool SoundManager::sayDone(const MWWorld::ConstPtr &ptr) const @@ -514,7 +509,7 @@ namespace MWSound SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr); if(snditer != mActiveSaySounds.end()) { - if(mOutput->isStreamPlaying(snditer->second)) + if(mOutput->isStreamPlaying(snditer->second.get())) return false; return true; } @@ -526,7 +521,7 @@ namespace MWSound SaySoundMap::const_iterator snditer = mSaySoundsQueue.find(ptr); if(snditer != mSaySoundsQueue.end()) { - if(mOutput->isStreamPlaying(snditer->second)) + if(mOutput->isStreamPlaying(snditer->second.get())) return true; return false; } @@ -534,7 +529,7 @@ namespace MWSound snditer = mActiveSaySounds.find(ptr); if(snditer != mActiveSaySounds.end()) { - if(mOutput->isStreamPlaying(snditer->second)) + if(mOutput->isStreamPlaying(snditer->second.get())) return true; return false; } @@ -547,16 +542,14 @@ namespace MWSound SaySoundMap::iterator snditer = mSaySoundsQueue.find(ptr); if(snditer != mSaySoundsQueue.end()) { - mOutput->finishStream(snditer->second); - mStreams.recycle(snditer->second); + mOutput->finishStream(snditer->second.get()); mSaySoundsQueue.erase(snditer); } snditer = mActiveSaySounds.find(ptr); if(snditer != mActiveSaySounds.end()) { - mOutput->finishStream(snditer->second); - mStreams.recycle(snditer->second); + mOutput->finishStream(snditer->second.get()); mActiveSaySounds.erase(snditer); } } @@ -567,27 +560,24 @@ namespace MWSound if(!mOutput->isInitialized()) return nullptr; - Stream *track = getStreamRef(); + StreamPtr track = getStreamRef(); track->init(1.0f, volumeFromType(type), 1.0f, PlayMode::NoEnv|type|Play_2D); - if(!mOutput->streamSound(decoder, track)) - { - mStreams.recycle(track); + if(!mOutput->streamSound(decoder, track.get())) return nullptr; - } - mActiveTracks.insert( - std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), track), track - ); - return track; + Stream* result = track.get(); + const auto it = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), track); + mActiveTracks.insert(it, std::move(track)); + return result; } void SoundManager::stopTrack(Stream *stream) { mOutput->finishStream(stream); - TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream); - if(iter != mActiveTracks.end() && *iter == stream) + TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream, + [] (const StreamPtr& lhs, Stream* rhs) { return lhs.get() < rhs; }); + if(iter != mActiveTracks.end() && iter->get() == stream) mActiveTracks.erase(iter); - mStreams.recycle(stream); } double SoundManager::getTrackTimeDelay(Stream *stream) @@ -596,7 +586,7 @@ namespace MWSound } - Sound *SoundManager::playSound(const std::string& soundId, float volume, float pitch, Type type, PlayMode mode, float offset) + Sound* SoundManager::playSound(const std::string& soundId, float volume, float pitch, Type type, PlayMode mode, float offset) { if(!mOutput->isInitialized()) return nullptr; @@ -607,13 +597,10 @@ namespace MWSound // Only one copy of given sound can be played at time, so stop previous copy stopSound(sfx, MWWorld::ConstPtr()); - Sound *sound = getSoundRef(); + SoundPtr sound = getSoundRef(); sound->init(volume * sfx->mVolume, volumeFromType(type), pitch, mode|type|Play_2D); - if(!mOutput->playSound(sound, sfx->mHandle, offset)) - { - mSounds.recycle(sound); + if(!mOutput->playSound(sound.get(), sfx->mHandle, offset)) return nullptr; - } if(sfx->mUses++ == 0) { @@ -621,8 +608,9 @@ namespace MWSound if(iter != mUnusedBuffers.end()) mUnusedBuffers.erase(iter); } - mActiveSounds[MWWorld::ConstPtr()].push_back(std::make_pair(sound, sfx)); - return sound; + Sound* result = sound.get(); + mActiveSounds[MWWorld::ConstPtr()].emplace_back(std::move(sound), sfx); + return result; } Sound *SoundManager::playSound3D(const MWWorld::ConstPtr &ptr, const std::string& soundId, @@ -644,23 +632,20 @@ namespace MWSound stopSound(sfx, ptr); bool played; - Sound *sound = getSoundRef(); + SoundPtr sound = getSoundRef(); if(!(mode&PlayMode::NoPlayerLocal) && ptr == MWMechanics::getPlayer()) { sound->init(volume * sfx->mVolume, volumeFromType(type), pitch, mode|type|Play_2D); - played = mOutput->playSound(sound, sfx->mHandle, offset); + played = mOutput->playSound(sound.get(), sfx->mHandle, offset); } else { sound->init(objpos, volume * sfx->mVolume, volumeFromType(type), pitch, sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D); - played = mOutput->playSound3D(sound, sfx->mHandle, offset); + played = mOutput->playSound3D(sound.get(), sfx->mHandle, offset); } if(!played) - { - mSounds.recycle(sound); return nullptr; - } if(sfx->mUses++ == 0) { @@ -668,8 +653,9 @@ namespace MWSound if(iter != mUnusedBuffers.end()) mUnusedBuffers.erase(iter); } - mActiveSounds[ptr].push_back(std::make_pair(sound, sfx)); - return sound; + Sound* result = sound.get(); + mActiveSounds[ptr].emplace_back(std::move(sound), sfx); + return result; } Sound *SoundManager::playSound3D(const osg::Vec3f& initialPos, const std::string& soundId, @@ -683,14 +669,11 @@ namespace MWSound Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); if(!sfx) return nullptr; - Sound *sound = getSoundRef(); + SoundPtr sound = getSoundRef(); sound->init(initialPos, volume * sfx->mVolume, volumeFromType(type), pitch, sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D); - if(!mOutput->playSound3D(sound, sfx->mHandle, offset)) - { - mSounds.recycle(sound); + if(!mOutput->playSound3D(sound.get(), sfx->mHandle, offset)) return nullptr; - } if(sfx->mUses++ == 0) { @@ -698,8 +681,9 @@ namespace MWSound if(iter != mUnusedBuffers.end()) mUnusedBuffers.erase(iter); } - mActiveSounds[MWWorld::ConstPtr()].push_back(std::make_pair(sound, sfx)); - return sound; + Sound* result = sound.get(); + mActiveSounds[MWWorld::ConstPtr()].emplace_back(std::move(sound), sfx); + return result; } void SoundManager::stopSound(Sound *sound) @@ -716,7 +700,7 @@ namespace MWSound for(SoundBufferRefPair &snd : snditer->second) { if(snd.second == sfx) - mOutput->finishSound(snd.first); + mOutput->finishSound(snd.first.get()); } } } @@ -738,14 +722,14 @@ namespace MWSound if(snditer != mActiveSounds.end()) { for(SoundBufferRefPair &snd : snditer->second) - mOutput->finishSound(snd.first); + mOutput->finishSound(snd.first.get()); } SaySoundMap::iterator sayiter = mSaySoundsQueue.find(ptr); if(sayiter != mSaySoundsQueue.end()) - mOutput->finishStream(sayiter->second); + mOutput->finishStream(sayiter->second.get()); sayiter = mActiveSaySounds.find(ptr); if(sayiter != mActiveSaySounds.end()) - mOutput->finishStream(sayiter->second); + mOutput->finishStream(sayiter->second.get()); } void SoundManager::stopSound(const MWWorld::CellStore *cell) @@ -755,20 +739,20 @@ namespace MWSound if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) { for(SoundBufferRefPair &sndbuf : snd.second) - mOutput->finishSound(sndbuf.first); + mOutput->finishSound(sndbuf.first.get()); } } for(SaySoundMap::value_type &snd : mSaySoundsQueue) { if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) - mOutput->finishStream(snd.second); + mOutput->finishStream(snd.second.get()); } for(SaySoundMap::value_type &snd : mActiveSaySounds) { if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) - mOutput->finishStream(snd.second); + mOutput->finishStream(snd.second.get()); } } @@ -795,7 +779,7 @@ namespace MWSound Sound_Buffer *sfx = lookupSound(Misc::StringUtils::lowerCase(soundId)); return std::find_if(snditer->second.cbegin(), snditer->second.cend(), [this,sfx](const SoundBufferRefPair &snd) -> bool - { return snd.second == sfx && mOutput->isSoundPlaying(snd.first); } + { return snd.second == sfx && mOutput->isSoundPlaying(snd.first.get()); } ) != snditer->second.cend(); } return false; @@ -912,7 +896,7 @@ namespace MWSound const auto pairiter = std::find_if( snditer->second.begin(), snditer->second.end(), [this](const SoundBufferRefPairList::value_type &item) -> bool - { return mNearWaterSound == item.first; } + { return mNearWaterSound == item.first.get(); } ); if (pairiter != snditer->second.end() && pairiter->second != sfx) soundIdChanged = true; @@ -938,7 +922,11 @@ namespace MWSound SaySoundMap::iterator queuesayiter = mSaySoundsQueue.begin(); while (queuesayiter != mSaySoundsQueue.end()) { - mActiveSaySounds[queuesayiter->first] = queuesayiter->second; + const auto dst = mActiveSaySounds.find(queuesayiter->first); + if (dst == mActiveSaySounds.end()) + mActiveSaySounds.emplace(queuesayiter->first, std::move(queuesayiter->second)); + else + dst->second = std::move(queuesayiter->second); mSaySoundsQueue.erase(queuesayiter++); } @@ -979,10 +967,9 @@ namespace MWSound SoundBufferRefPairList::iterator sndidx = snditer->second.begin(); while(sndidx != snditer->second.end()) { - Sound *sound; - Sound_Buffer *sfx; + Sound *sound = sndidx->first.get(); + Sound_Buffer *sfx = sndidx->second; - std::tie(sound, sfx) = *sndidx; if(!ptr.isEmpty() && sound->getIs3D()) { const ESM::Position &pos = ptr.getRefData().getPosition(); @@ -999,10 +986,9 @@ namespace MWSound if(!mOutput->isSoundPlaying(sound)) { mOutput->finishSound(sound); - mSounds.recycle(sound); - if(sound == mUnderwaterSound) + if (sound == mUnderwaterSound) mUnderwaterSound = nullptr; - if(sound == mNearWaterSound) + if (sound == mNearWaterSound) mNearWaterSound = nullptr; if(sfx->mUses-- == 1) mUnusedBuffers.push_front(sfx); @@ -1026,7 +1012,7 @@ namespace MWSound while(sayiter != mActiveSaySounds.end()) { MWWorld::ConstPtr ptr = sayiter->first; - Stream *sound = sayiter->second; + Stream *sound = sayiter->second.get(); if(!ptr.isEmpty() && sound->getIs3D()) { MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -1043,7 +1029,6 @@ namespace MWSound if(!mOutput->isStreamPlaying(sound)) { mOutput->finishStream(sound); - mStreams.recycle(sound); mActiveSaySounds.erase(sayiter++); } else @@ -1058,7 +1043,7 @@ namespace MWSound TrackList::iterator trkiter = mActiveTracks.begin(); for(;trkiter != mActiveTracks.end();++trkiter) { - Stream *sound = *trkiter; + Stream *sound = trkiter->get(); if(!mOutput->isStreamPlaying(sound)) { mOutput->finishStream(sound); @@ -1089,7 +1074,7 @@ namespace MWSound { mMusic->updateFade(duration); - mOutput->updateStream(mMusic); + mOutput->updateStream(mMusic.get()); if (mMusic->getRealVolume() <= 0.f) { @@ -1126,32 +1111,32 @@ namespace MWSound { for(SoundBufferRefPair &sndbuf : snd.second) { - Sound *sound = sndbuf.first; + Sound *sound = sndbuf.first.get(); sound->setBaseVolume(volumeFromType(sound->getPlayType())); mOutput->updateSound(sound); } } for(SaySoundMap::value_type &snd : mActiveSaySounds) { - Stream *sound = snd.second; + Stream *sound = snd.second.get(); sound->setBaseVolume(volumeFromType(sound->getPlayType())); mOutput->updateStream(sound); } for(SaySoundMap::value_type &snd : mSaySoundsQueue) { - Stream *sound = snd.second; + Stream *sound = snd.second.get(); sound->setBaseVolume(volumeFromType(sound->getPlayType())); mOutput->updateStream(sound); } - for(Stream *sound : mActiveTracks) + for (const StreamPtr& sound : mActiveTracks) { sound->setBaseVolume(volumeFromType(sound->getPlayType())); - mOutput->updateStream(sound); + mOutput->updateStream(sound.get()); } if(mMusic) { mMusic->setBaseVolume(volumeFromType(mMusic->getPlayType())); - mOutput->updateStream(mMusic); + mOutput->updateStream(mMusic.get()); } mOutput->finishUpdate(); } @@ -1180,17 +1165,17 @@ namespace MWSound SaySoundMap::iterator sayiter = mSaySoundsQueue.find(old); if(sayiter != mSaySoundsQueue.end()) { - Stream *stream = sayiter->second; + StreamPtr stream = std::move(sayiter->second); mSaySoundsQueue.erase(sayiter); - mSaySoundsQueue.emplace(updated, stream); + mSaySoundsQueue.emplace(updated, std::move(stream)); } sayiter = mActiveSaySounds.find(old); if(sayiter != mActiveSaySounds.end()) { - Stream *stream = sayiter->second; + StreamPtr stream = std::move(sayiter->second); mActiveSaySounds.erase(sayiter); - mActiveSaySounds.emplace(updated, stream); + mActiveSaySounds.emplace(updated, std::move(stream)); } } @@ -1267,8 +1252,7 @@ namespace MWSound { for(SoundBufferRefPair &sndbuf : snd.second) { - mOutput->finishSound(sndbuf.first); - mSounds.recycle(sndbuf.first); + mOutput->finishSound(sndbuf.first.get()); Sound_Buffer *sfx = sndbuf.second; if(sfx->mUses-- == 1) mUnusedBuffers.push_front(sfx); @@ -1279,24 +1263,15 @@ namespace MWSound mNearWaterSound = nullptr; for(SaySoundMap::value_type &snd : mSaySoundsQueue) - { - mOutput->finishStream(snd.second); - mStreams.recycle(snd.second); - } + mOutput->finishStream(snd.second.get()); mSaySoundsQueue.clear(); for(SaySoundMap::value_type &snd : mActiveSaySounds) - { - mOutput->finishStream(snd.second); - mStreams.recycle(snd.second); - } + mOutput->finishStream(snd.second.get()); mActiveSaySounds.clear(); - for(Stream *sound : mActiveTracks) - { - mOutput->finishStream(sound); - mStreams.recycle(sound); - } + for(StreamPtr& sound : mActiveTracks) + mOutput->finishStream(sound.get()); mActiveTracks.clear(); mPlaybackPaused = false; std::fill(std::begin(mPausedSoundTypes), std::end(mPausedSoundTypes), 0); diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index e03bd7b1f..b3f612d7d 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -48,6 +48,9 @@ namespace MWSound Play_3D = 1<<31 }; + using SoundPtr = Misc::ObjectPtr; + using StreamPtr = Misc::ObjectPtr; + class SoundManager : public MWBase::SoundManager { const VFS::Manager* mVFS; @@ -83,19 +86,19 @@ namespace MWSound Misc::ObjectPool mStreams; - typedef std::pair SoundBufferRefPair; + typedef std::pair SoundBufferRefPair; typedef std::vector SoundBufferRefPairList; typedef std::map SoundMap; SoundMap mActiveSounds; - typedef std::map SaySoundMap; + typedef std::map SaySoundMap; SaySoundMap mSaySoundsQueue; SaySoundMap mActiveSaySounds; - typedef std::vector TrackList; + typedef std::vector TrackList; TrackList mActiveTracks; - Stream *mMusic; + StreamPtr mMusic; std::string mCurrentPlaylist; bool mListenerUnderwater; @@ -125,10 +128,10 @@ namespace MWSound // returns a decoder to start streaming, or nullptr if the sound was not found DecoderPtr loadVoice(const std::string &voicefile); - Sound *getSoundRef(); - Stream *getStreamRef(); + SoundPtr getSoundRef(); + StreamPtr getStreamRef(); - Stream *playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal); + StreamPtr playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal); void streamMusicFull(const std::string& filename); void advanceMusic(const std::string& filename); diff --git a/components/misc/objectpool.hpp b/components/misc/objectpool.hpp index 97a055331..b3dae6a4f 100644 --- a/components/misc/objectpool.hpp +++ b/components/misc/objectpool.hpp @@ -7,14 +7,51 @@ namespace Misc { + template + class ObjectPool; + + template + class ObjectPtrDeleter + { + public: + ObjectPtrDeleter(std::nullptr_t) + : mPool(nullptr) {} + + ObjectPtrDeleter(ObjectPool& pool) + : mPool(&pool) {} + + void operator()(T* object) const + { + mPool->recycle(object); + } + + private: + ObjectPool* mPool; + }; + + template + struct ObjectPtr final : std::unique_ptr> + { + using std::unique_ptr>::unique_ptr; + using std::unique_ptr>::operator=; + + ObjectPtr() + : ObjectPtr(nullptr) {} + + ObjectPtr(std::nullptr_t) + : std::unique_ptr>(nullptr, nullptr) {} + }; + template class ObjectPool { + friend class ObjectPtrDeleter; + public: ObjectPool() : mObjects(std::make_unique>()) {} - T* get() + ObjectPtr get() { T* object; @@ -29,17 +66,17 @@ namespace Misc object = &mObjects->back(); } - return object; + return ObjectPtr(object, ObjectPtrDeleter(*this)); } + private: + std::unique_ptr> mObjects; + std::vector mUnused; + void recycle(T* object) { mUnused.push_back(object); } - - private: - std::unique_ptr> mObjects; - std::vector mUnused; }; } From db75398fba426a9a535a0a37f3dddb415c9826ca Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sat, 4 Jul 2020 11:54:19 +0200 Subject: [PATCH 10/33] only build openmw for now --- CI/before_script.osx.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 7438c6c7a..9697c757c 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -17,6 +17,8 @@ cmake \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.9" \ -D CMAKE_BUILD_TYPE=DEBUG \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ +-D BUILD_OPENMW=TRUE \ +-D BUILD_OPENCS=FALSE \ -D BUILD_ESMTOOL=FALSE \ -D BUILD_BSATOOL=FALSE \ -D BUILD_ESSIMPORTER=FALSE \ From 2ac4a2c6e364cbc746ba950a9653ac871058ff95 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sat, 4 Jul 2020 13:22:58 +0200 Subject: [PATCH 11/33] do not make package for now --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cfc449434..cd0e6e713 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,7 +71,7 @@ before_script: script: - cd ./build - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ${ANALYZE} make -j3; fi - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi +# - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi # - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi From dc6fbd39d880e93d56a8f671be2859ee4dea6abe Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Tue, 7 Jan 2020 19:49:53 +1300 Subject: [PATCH 12/33] Cache compilation using ccache --- .gitlab-ci.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1f8bc6417..e58d3a498 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,19 +7,24 @@ Debian: - linux image: debian:bullseye cache: - key: apt-cache + key: cache.002 paths: - apt-cache/ + - ccache/ before_script: - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR - apt-get update -yq - - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev + - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev ccache stage: build - script: + script: + - export CCACHE_BASEDIR="`pwd`" + - export CCACHE_DIR="`pwd`/ccache" && mkdir -pv "$CCACHE_DIR" + - ccache -z -M 250M - cores_to_use=$((`nproc`-2)); if (( $cores_to_use < 1 )); then cores_to_use=1; fi - - mkdir build; cd build; cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../ + - mkdir build; cd build; cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../ -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - make -j$cores_to_use - DESTDIR=artifacts make install + - ccache -s artifacts: paths: - build/artifacts/ From 14d5b3eeaf65f1ac259c538a703be0e9e175c07e Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Mon, 6 Jul 2020 07:47:31 +0200 Subject: [PATCH 13/33] try release again and turning on bit by bit for ccache to be used --- CI/before_script.osx.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 9697c757c..15d6862db 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -14,14 +14,16 @@ cmake \ -D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \ -D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \ -D CMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" \ +-D CMAKE_C_FLAGS_RELEASE="-g -O0" \ +-D CMAKE_CXX_FLAGS_RELEASE="-g -O0" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.9" \ --D CMAKE_BUILD_TYPE=DEBUG \ +-D CMAKE_BUILD_TYPE=RELEASE \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D BUILD_OPENMW=TRUE \ -D BUILD_OPENCS=FALSE \ --D BUILD_ESMTOOL=FALSE \ --D BUILD_BSATOOL=FALSE \ --D BUILD_ESSIMPORTER=FALSE \ --D BUILD_NIFTEST=FALSE \ +-D BUILD_ESMTOOL=TRUE \ +-D BUILD_BSATOOL=TRUE \ +-D BUILD_ESSIMPORTER=TRUE \ +-D BUILD_NIFTEST=TRUE \ -G"Unix Makefiles" \ .. From 3c460fb3e93a282a768f0ad1efce7ab9d309ed04 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 28 Jun 2020 22:50:06 +0200 Subject: [PATCH 14/33] Use pointer to Sound to stop sounds started by NpcAnimation --- apps/openmw/mwrender/npcanimation.cpp | 14 ++++++++------ apps/openmw/mwrender/npcanimation.hpp | 9 ++++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 6e7669976..c6a0b15bd 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -349,6 +349,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr par mPartPriorities[i] = 0; } + std::fill(mSounds.begin(), mSounds.end(), nullptr); + updateNpcBase(); } @@ -756,10 +758,10 @@ void NpcAnimation::removeIndividualPart(ESM::PartReferenceType type) mPartslots[type] = -1; mObjectParts[type].reset(); - if (!mSoundIds[type].empty() && !mSoundsDisabled) + if (mSounds[type] != nullptr && !mSoundsDisabled) { - MWBase::Environment::get().getSoundManager()->stopSound3D(mPtr, mSoundIds[type]); - mSoundIds[type].clear(); + MWBase::Environment::get().getSoundManager()->stopSound(mSounds[type]); + mSounds[type] = nullptr; } } @@ -838,10 +840,10 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g MWWorld::ConstContainerStoreIterator csi = inv.getSlot(group < 0 ? MWWorld::InventoryStore::Slot_Helmet : group); if (csi != inv.end()) { - mSoundIds[type] = csi->getClass().getSound(*csi); - if (!mSoundIds[type].empty()) + const auto soundId = csi->getClass().getSound(*csi); + if (!soundId.empty()) { - MWBase::Environment::get().getSoundManager()->playSound3D(mPtr, mSoundIds[type], + mSounds[type] = MWBase::Environment::get().getSoundManager()->playSound3D(mPtr, soundId, 1.0f, 1.0f, MWSound::Type::Sfx, MWSound::PlayMode::Loop ); } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 7f8d5434b..7edf35a5c 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -8,12 +8,19 @@ #include "actoranimation.hpp" #include "weaponanimation.hpp" +#include + namespace ESM { struct NPC; struct BodyPart; } +namespace MWSound +{ + class Sound; +} + namespace MWRender { @@ -40,7 +47,7 @@ private: // Bounded Parts PartHolderPtr mObjectParts[ESM::PRT_Count]; - std::string mSoundIds[ESM::PRT_Count]; + std::array mSounds; const ESM::NPC *mNpc; std::string mHeadModel; From 281cef9769b1ea68b1451b08b76c7c9b41accb5a Mon Sep 17 00:00:00 2001 From: CedricMocquillon Date: Mon, 6 Jul 2020 20:28:08 +0200 Subject: [PATCH 15/33] The 3 skill selected by a trainer are based on its 3 best skills. The skills are sorted either on their base value or on their modified one depending on the new setting 'trainers training skills based on base skill' --- apps/openmw/mwgui/trainingwindow.cpp | 16 +++++++++++++++- files/settings-default.cfg | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index e4e4bae5a..91e9ce3cb 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -14,6 +14,8 @@ #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include + #include "tooltips.hpp" namespace @@ -32,6 +34,17 @@ bool sortSkills (const std::pair& left, const std::pair& rig return left.first < right.first; } + +// Retrieve the base skill value if the setting 'training skills based on base skill' is set; +// otherwise returns the modified skill +float getSkillForTraining(const MWMechanics::NpcStats& stats, int i) +{ + static const bool trainersTrainingSkillsBasedOnBaseSkill = Settings::Manager::getBool("trainers training skills based on base skill", "Game"); + if (trainersTrainingSkillsBasedOnBaseSkill) + return stats.getSkill(i).getBase(); + return stats.getSkill(i).getModified(); +} + } namespace MWGui @@ -76,9 +89,10 @@ namespace MWGui // NPC can train you in his best 3 skills std::vector< std::pair > skills; + MWMechanics::NpcStats const& actorStats(actor.getClass().getNpcStats(actor)); for (int i=0; i Date: Mon, 6 Jul 2020 20:30:14 +0200 Subject: [PATCH 16/33] The number of skills points a trainer can teach is based either on its base values or on its modified ones depending on the new setting 'trainers training skills based on base skill' value --- apps/openmw/mwgui/trainingwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 91e9ce3cb..60eb797ee 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -154,7 +154,7 @@ namespace MWGui if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId)) return; - if (mPtr.getClass().getSkill(mPtr, skillId) <= pcStats.getSkill (skillId).getBase ()) + if (getSkillForTraining(mPtr.getClass().getNpcStats(mPtr), skillId) <= pcStats.getSkill(skillId).getBase()) { MWBase::Environment::get().getWindowManager()->messageBox ("#{sServiceTrainingWords}"); return; From 998bf5da34f745202d823ef7bc3ad971bf64bd81 Mon Sep 17 00:00:00 2001 From: CedricMocquillon Date: Mon, 6 Jul 2020 20:32:30 +0200 Subject: [PATCH 17/33] Add new checkbox for the new setting 'trainers training skills based on base skill' --- apps/launcher/advancedpage.cpp | 2 ++ files/ui/advancedpage.ui | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 866cec728..e9db74cae 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -90,6 +90,7 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); } loadSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); + loadSettingBool(trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); // Input Settings loadSettingBool(grabCursorCheckBox, "grab cursor", "Input"); @@ -155,6 +156,7 @@ void Launcher::AdvancedPage::saveSettings() saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); saveSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); saveSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); + saveSettingBool(trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); // Input Settings saveSettingBool(grabCursorCheckBox, "grab cursor", "Input"); diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 03b011b47..142cd7259 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -236,6 +236,16 @@ + + + + <html><head/><body><p>Trainers now only choose which skills to train using their base skill points, allowing mercantile improving effects to be used without making mercantile an offered skill.</p></body></html> + + + Trainers choose their training skills based on their base skill points + + + From 096e25b29a590a4667ab04046f1d2fd69517c7d3 Mon Sep 17 00:00:00 2001 From: CedricMocquillon Date: Tue, 7 Jul 2020 09:50:02 +0200 Subject: [PATCH 18/33] Make the getSkillForTraining a member method of TrainingWindow class. The implementation is based now on the member of the class mTrainingSkillBasedOnBaseSkill instead of local static --- apps/openmw/mwgui/trainingwindow.cpp | 19 ++++++++----------- apps/openmw/mwgui/trainingwindow.hpp | 10 ++++++++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 60eb797ee..d0176ece4 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -34,17 +34,6 @@ bool sortSkills (const std::pair& left, const std::pair& rig return left.first < right.first; } - -// Retrieve the base skill value if the setting 'training skills based on base skill' is set; -// otherwise returns the modified skill -float getSkillForTraining(const MWMechanics::NpcStats& stats, int i) -{ - static const bool trainersTrainingSkillsBasedOnBaseSkill = Settings::Manager::getBool("trainers training skills based on base skill", "Game"); - if (trainersTrainingSkillsBasedOnBaseSkill) - return stats.getSkill(i).getBase(); - return stats.getSkill(i).getModified(); -} - } namespace MWGui @@ -53,6 +42,7 @@ namespace MWGui TrainingWindow::TrainingWindow() : WindowBase("openmw_trainingwindow.layout") , mTimeAdvancer(0.05f) + , mTrainingSkillBasedOnBaseSkill(Settings::Manager::getBool("trainers training skills based on base skill", "Game")) { getWidget(mTrainingOptions, "TrainingOptions"); getWidget(mCancelButton, "CancelButton"); @@ -209,6 +199,13 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); } + float TrainingWindow::getSkillForTraining(const MWMechanics::NpcStats& stats, int skillId) const + { + if (mTrainingSkillBasedOnBaseSkill) + return stats.getSkill(skillId).getBase(); + return stats.getSkill(skillId).getModified(); + } + void TrainingWindow::onFrame(float dt) { checkReferenceAvailable(); diff --git a/apps/openmw/mwgui/trainingwindow.hpp b/apps/openmw/mwgui/trainingwindow.hpp index 2edad1f27..955615516 100644 --- a/apps/openmw/mwgui/trainingwindow.hpp +++ b/apps/openmw/mwgui/trainingwindow.hpp @@ -6,6 +6,11 @@ #include "timeadvancer.hpp" #include "waitdialog.hpp" +namespace MWMechanics +{ + class NpcStats; +} + namespace MWGui { @@ -35,12 +40,17 @@ namespace MWGui void onTrainingProgressChanged(int cur, int total); void onTrainingFinished(); + // Retrieve the base skill value if the setting 'training skills based on base skill' is set; + // otherwise returns the modified skill + float getSkillForTraining(const MWMechanics::NpcStats& stats, int skillId) const; + MyGUI::Widget* mTrainingOptions; MyGUI::Button* mCancelButton; MyGUI::TextBox* mPlayerGold; WaitDialogProgressBar mProgressBar; TimeAdvancer mTimeAdvancer; + bool mTrainingSkillBasedOnBaseSkill; //corresponds to the setting 'training skills based on base skill' }; } From e51191b5ca6858c187ccbafea1dfeb8c4ca789ad Mon Sep 17 00:00:00 2001 From: CedricMocquillon Date: Tue, 7 Jul 2020 17:54:31 +0200 Subject: [PATCH 19/33] Update documentation --- docs/source/reference/modding/settings/game.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/source/reference/modding/settings/game.rst b/docs/source/reference/modding/settings/game.rst index c27796aec..9cac845a5 100644 --- a/docs/source/reference/modding/settings/game.rst +++ b/docs/source/reference/modding/settings/game.rst @@ -330,3 +330,18 @@ If disabled then the whole character's body is pointed to the direction of view. If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it also changes straight right and straight left movement. This setting can only be configured by editing the settings configuration file. + +trainers training skills based on base skill +----------------------- + +:Type: boolean +:Range: True/False +:Default: False + +The trainers in Morrowind choose their proposed training skills based on their 3 best attributes. + +If disabled then the 3 best skills of trainers and the training limits take into account fortified/drained trainer skill. + +If enabled then the 3 best skills of trainers and the training limits are based on the trainer base skills. + +This setting can be controlled in Advanced tab of the launcher. From d76b81a4a43cf3bce0c98fa355d9c4746889e5bd Mon Sep 17 00:00:00 2001 From: CedricMocquillon Date: Tue, 7 Jul 2020 17:54:42 +0200 Subject: [PATCH 20/33] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 687e421fa..c2f05c3c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Feature #5362: Show the soul gems' trapped soul in count dialog Feature #5445: Handle NiLines Feature #5457: Realistic diagonal movement + Feature #5486: Fixes trainers to choose their training skills based on their base skill points Task #5480: Drop Qt4 support 0.46.0 From 624baa6d89679406fccd1314c2b00626d2fc0c7a Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 28 Jun 2020 19:59:53 +0200 Subject: [PATCH 21/33] Check distance to object before load sound --- apps/openmw/mwsound/soundmanagerimp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index eed935e61..eabda4cc3 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -620,14 +620,14 @@ namespace MWSound if(!mOutput->isInitialized()) return nullptr; + const osg::Vec3f objpos(ptr.getRefData().getPosition().asVec3()); + if ((mode & PlayMode::RemoveAtDistance) && (mListenerPos - objpos).length2() > 2000 * 2000) + return nullptr; + // Look up the sound in the ESM data Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); if(!sfx) return nullptr; - const osg::Vec3f objpos(ptr.getRefData().getPosition().asVec3()); - if((mode&PlayMode::RemoveAtDistance) && (mListenerPos-objpos).length2() > 2000*2000) - return nullptr; - // Only one copy of given sound can be played at time on ptr, so stop previous copy stopSound(sfx, ptr); From 1c9ce03575d0834cb8aa556d594ee03693ff1644 Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 29 Jun 2020 00:05:25 +0200 Subject: [PATCH 22/33] Lookup sound when need to fade out --- apps/openmw/mwsound/soundmanagerimp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index eabda4cc3..a4241fef2 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -762,7 +762,9 @@ namespace MWSound SoundMap::iterator snditer = mActiveSounds.find(ptr); if(snditer != mActiveSounds.end()) { - Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); + Sound_Buffer *sfx = lookupSound(Misc::StringUtils::lowerCase(soundId)); + if (sfx == nullptr) + return; for(SoundBufferRefPair &sndbuf : snditer->second) { if(sndbuf.second == sfx) From 46db69a3490bc0d3110fdeac6d93b399e1969565 Mon Sep 17 00:00:00 2001 From: psi29a Date: Thu, 9 Jul 2020 06:47:37 +0000 Subject: [PATCH 23/33] Merge branch 'swimming' into 'master' Swimming-related fixes See merge request OpenMW/openmw!247 (cherry picked from commit 8be328ef80f29e9692e29d24beefa8ced16537a7) 738c71fd Extend the "turn to movement direction" mode for swimming up and down. 10d3e82b New setting "swim upward coef" --- apps/openmw/mwmechanics/character.cpp | 26 ++++++++++++++++--- apps/openmw/mwrender/animation.cpp | 5 ++-- apps/openmw/mwrender/animation.hpp | 3 +++ apps/openmw/mwrender/creatureanimation.cpp | 2 +- apps/openmw/mwrender/npcanimation.cpp | 2 +- .../reference/modding/settings/game.rst | 13 +++++++++- files/settings-default.cfg | 3 +++ 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index cf09fa6f7..aed638895 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1914,6 +1914,7 @@ void CharacterController::update(float duration, bool animationOnly) mTimeUntilWake -= duration; bool isPlayer = mPtr == MWMechanics::getPlayer(); + bool isFirstPersonPlayer = isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson(); bool godmode = isPlayer && MWBase::Environment::get().getWorld()->getGodModeState(); float scale = mPtr.getCellRef().getScale(); @@ -1977,7 +1978,7 @@ void CharacterController::update(float duration, bool animationOnly) float effectiveRotation = rot.z(); static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game"); - if (turnToMovementDirection && !(isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson())) + if (turnToMovementDirection && !isFirstPersonPlayer) { float targetMovementAngle = vec.y() >= 0 ? std::atan2(-vec.x(), vec.y()) : std::atan2(vec.x(), -vec.y()); movementSettings.mIsStrafing = (stats.getDrawState() != MWMechanics::DrawState_Nothing || inwater) @@ -2206,8 +2207,7 @@ void CharacterController::update(float duration, bool animationOnly) // It seems only bipedal actors use turning animations. // Also do not use turning animations in the first-person view and when sneaking. - bool isFirstPlayer = isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson(); - if (!sneak && jumpstate == JumpState_None && !isFirstPlayer && mPtr.getClass().isBipedal(mPtr)) + if (!sneak && jumpstate == JumpState_None && !isFirstPersonPlayer && mPtr.getClass().isBipedal(mPtr)) { if(effectiveRotation > rotationThreshold) movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight; @@ -2231,6 +2231,26 @@ void CharacterController::update(float duration, bool animationOnly) sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal); } + if (turnToMovementDirection) + { + float targetSwimmingPitch; + if (inwater && vec.y() != 0 && !isFirstPersonPlayer && !movementSettings.mIsStrafing) + targetSwimmingPitch = -mPtr.getRefData().getPosition().rot[0]; + else + targetSwimmingPitch = 0; + float maxSwimPitchDelta = 3.0f * duration; + float swimmingPitch = mAnimation->getBodyPitchRadians(); + swimmingPitch += osg::clampBetween(targetSwimmingPitch - swimmingPitch, -maxSwimPitchDelta, maxSwimPitchDelta); + mAnimation->setBodyPitchRadians(swimmingPitch); + } + if (inwater && isPlayer && !isFirstPersonPlayer) + { + static const float swimUpwardCoef = Settings::Manager::getFloat("swim upward coef", "Game"); + static const float swimForwardCoef = sqrtf(1.0f - swimUpwardCoef * swimUpwardCoef); + vec.z() = std::abs(vec.y()) * swimUpwardCoef; + vec.y() *= swimForwardCoef; + } + // Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering if (isPlayer) { diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 688937ce9..3835e26de 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -623,6 +623,7 @@ namespace MWRender , mHeadPitchRadians(0.f) , mUpperBodyYawRadians(0.f) , mLegsYawRadians(0.f) + , mBodyPitchRadians(0.f) , mHasMagicEffects(false) , mAlpha(1.f) { @@ -1340,11 +1341,11 @@ namespace MWRender float yawOffset = 0; if (mRootController) { - bool enable = std::abs(mLegsYawRadians) > epsilon; + bool enable = std::abs(mLegsYawRadians) > epsilon || std::abs(mBodyPitchRadians) > epsilon; mRootController->setEnabled(enable); if (enable) { - mRootController->setRotate(osg::Quat(mLegsYawRadians, osg::Vec3f(0,0,1))); + mRootController->setRotate(osg::Quat(mLegsYawRadians, osg::Vec3f(0,0,1)) * osg::Quat(mBodyPitchRadians, osg::Vec3f(1,0,0))); yawOffset = mLegsYawRadians; } } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 564952a90..a04a3f999 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -273,6 +273,7 @@ protected: float mHeadPitchRadians; float mUpperBodyYawRadians; float mLegsYawRadians; + float mBodyPitchRadians; RotateController* addRotateController(std::string bone); @@ -489,6 +490,8 @@ public: virtual void setLegsYawRadians(float v) { mLegsYawRadians = v; } virtual float getUpperBodyYawRadians() const { return mUpperBodyYawRadians; } virtual float getLegsYawRadians() const { return mLegsYawRadians; } + virtual void setBodyPitchRadians(float v) { mBodyPitchRadians = v; } + virtual float getBodyPitchRadians() const { return mBodyPitchRadians; } virtual void setAccurateAiming(bool enabled) {} virtual bool canBeHarvested() const { return false; } diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 8e7f30687..489a7a987 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -273,7 +273,7 @@ osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration) { osg::Vec3f ret = Animation::runAnimation(duration); - WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0]); + WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians()); return ret; } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index c6a0b15bd..468938d22 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -747,7 +747,7 @@ osg::Vec3f NpcAnimation::runAnimation(float timepassed) mFirstPersonNeckController->setOffset(mFirstPersonOffset); } - WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0]); + WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians()); return ret; } diff --git a/docs/source/reference/modding/settings/game.rst b/docs/source/reference/modding/settings/game.rst index 9cac845a5..8d0b0dfc1 100644 --- a/docs/source/reference/modding/settings/game.rst +++ b/docs/source/reference/modding/settings/game.rst @@ -331,8 +331,19 @@ If enabled then the character turns lower body to the direction of movement. Upp This setting can only be configured by editing the settings configuration file. +swim upward coef +---------------- + +:Type: floating point +:Range: -1.0 to 1.0 +:Default: 0.0 + +Makes player swim a bit upward (or downward in case of negative value) from the line of sight. Intended to make simpler swimming without diving. Recommened range of values is from 0.0 to 0.2. + +This setting can only be configured by editing the settings configuration file. + trainers training skills based on base skill ------------------------ +-------------------------------------------- :Type: boolean :Range: True/False diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 494b06092..b044bdd5c 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -310,6 +310,9 @@ uncapped damage fatigue = false # Turn lower body to movement direction. 'true' makes diagonal movement more realistic. turn to movement direction = false +# Makes player swim a bit upward (or downward in case of negative value) from the line of sight. +swim upward coef = 0.0 + # Make the training skills proposed by a trainer based on its base attribute instead of its modified ones trainers training skills based on base skill = false From bbba524a6c336d6910ab2a1bc34a6902316e5032 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Thu, 9 Jul 2020 22:36:57 +0200 Subject: [PATCH 24/33] Resolves #5517 by removing the object being rotated from the paging system. --- apps/openmw/mwworld/worldimp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index d8b822242..fd934b8a8 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1390,6 +1390,9 @@ namespace MWWorld { if(ptr.getRefData().getBaseNode() != 0) { + mRendering->pagingBlacklistObject(mStore.find(ptr.getCellRef().getRefId()), ptr); + mWorldScene->removeFromPagedRefs(ptr); + mRendering->rotateObject(ptr, rotate); mPhysics->updateRotation(ptr); From 4ea018c594929e4beacad0009942a094b45fddd8 Mon Sep 17 00:00:00 2001 From: bzzt lost a hitlab login Date: Thu, 9 Jul 2020 23:17:01 +0200 Subject: [PATCH 25/33] Should resolve #5493 by better supporting objects that are placed across cells. --- apps/openmw/mwrender/objectpaging.cpp | 17 +++++++++++++++-- apps/openmw/mwrender/objectpaging.hpp | 4 ++-- apps/openmw/mwrender/renderingmanager.cpp | 4 ++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index fd12ad367..0f7e1c422 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -670,16 +670,27 @@ namespace MWRender { if (mActiveGridOnly && !std::get<2>(id)) return false; pos /= ESM::Land::REAL_SIZE; + clampToCell(pos); osg::Vec2f center = std::get<0>(id); float halfSize = std::get<1>(id)/2; return pos.x() >= center.x()-halfSize && pos.y() >= center.y()-halfSize && pos.x() <= center.x()+halfSize && pos.y() <= center.y()+halfSize; } + void clampToCell(osg::Vec3f& cellPos) + { + osg::Vec2i min (mCell.x(), mCell.y()); + osg::Vec2i max (mCell.x()+1, mCell.y()+1); + if (cellPos.x() < min.x()) cellPos.x() = min.x(); + if (cellPos.x() > max.x()) cellPos.x() = max.x(); + if (cellPos.y() < min.y()) cellPos.y() = min.y(); + if (cellPos.y() > max.y()) cellPos.y() = max.y(); + } osg::Vec3f mPosition; + osg::Vec2i mCell; std::set mToClear; bool mActiveGridOnly = false; }; - bool ObjectPaging::enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, bool enabled) + bool ObjectPaging::enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell, bool enabled) { if (!typeFilter(type, false)) return false; @@ -693,6 +704,7 @@ namespace MWRender ClearCacheFunctor ccf; ccf.mPosition = pos; + ccf.mCell = cell; mCache->call(ccf); if (ccf.mToClear.empty()) return false; for (auto chunk : ccf.mToClear) @@ -700,7 +712,7 @@ namespace MWRender return true; } - bool ObjectPaging::blacklistObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos) + bool ObjectPaging::blacklistObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell) { if (!typeFilter(type, false)) return false; @@ -713,6 +725,7 @@ namespace MWRender ClearCacheFunctor ccf; ccf.mPosition = pos; + ccf.mCell = cell; ccf.mActiveGridOnly = true; mCache->call(ccf); if (ccf.mToClear.empty()) return false; diff --git a/apps/openmw/mwrender/objectpaging.hpp b/apps/openmw/mwrender/objectpaging.hpp index 2ca302038..18fa30289 100644 --- a/apps/openmw/mwrender/objectpaging.hpp +++ b/apps/openmw/mwrender/objectpaging.hpp @@ -34,10 +34,10 @@ namespace MWRender virtual unsigned int getNodeMask() override; /// @return true if view needs rebuild - bool enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, bool enabled); + bool enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell, bool enabled); /// @return true if view needs rebuild - bool blacklistObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos); + bool blacklistObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell); void clear(); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 0c6e48645..a7d9003dc 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1517,7 +1517,7 @@ namespace MWRender { if (!ptr.isInCell() || !ptr.getCell()->isExterior() || !mObjectPaging) return false; - if (mObjectPaging->enableObject(type, ptr.getCellRef().getRefNum(), ptr.getCellRef().getPosition().asVec3(), enabled)) + if (mObjectPaging->enableObject(type, ptr.getCellRef().getRefNum(), ptr.getCellRef().getPosition().asVec3(), osg::Vec2i(ptr.getCell()->getCell()->getGridX(), ptr.getCell()->getCell()->getGridY()), enabled)) { mTerrain->rebuildViews(); return true; @@ -1530,7 +1530,7 @@ namespace MWRender return; const ESM::RefNum & refnum = ptr.getCellRef().getRefNum(); if (!refnum.hasContentFile()) return; - if (mObjectPaging->blacklistObject(type, refnum, ptr.getCellRef().getPosition().asVec3())) + if (mObjectPaging->blacklistObject(type, refnum, ptr.getCellRef().getPosition().asVec3(), osg::Vec2i(ptr.getCell()->getCell()->getGridX(), ptr.getCell()->getCell()->getGridY()))) mTerrain->rebuildViews(); } bool RenderingManager::pagingUnlockCache() From 280862f58b5af9bf0b099ccf16ffb42b6bc898dc Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Tue, 23 Jun 2020 20:05:22 +0200 Subject: [PATCH 26/33] New setting "third person camera distance" --- apps/openmw/mwrender/camera.cpp | 8 ++++++-- apps/openmw/mwrender/camera.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 6 +++--- docs/source/reference/modding/settings/camera.rst | 11 +++++++++++ files/settings-default.cfg | 3 +++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 148aa33ed..09ad40428 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -56,7 +57,7 @@ namespace MWRender mFurthest(800.f), mIsNearest(false), mHeight(124.f), - mBaseCameraDistance(192.f), + mBaseCameraDistance(Settings::Manager::getFloat("third person camera distance", "Camera")), mVanityToggleQueued(false), mVanityToggleQueuedValue(false), mViewModeToggleQueued(false), @@ -380,7 +381,7 @@ namespace MWRender return mCameraDistance; } - void Camera::setBaseCameraDistance(float dist, bool adjust) + void Camera::updateBaseCameraDistance(float dist, bool adjust) { if(mFirstPersonView && !mPreviewMode && !mVanity.enabled) return; @@ -407,7 +408,10 @@ namespace MWRender if (mVanity.enabled || mPreviewMode) mPreviewCam.offset = dist; else if (!mFirstPersonView) + { mBaseCameraDistance = dist; + Settings::Manager::setFloat("third person camera distance", "Camera", dist); + } setCameraDistance(); } diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index c04bf31c2..6398f4825 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -119,7 +119,7 @@ namespace MWRender /// Set base camera distance for current mode. Don't work on 1st person view. /// \param adjust Indicates should distance be adjusted or set. - void setBaseCameraDistance(float dist, bool adjust = false); + void updateBaseCameraDistance(float dist, bool adjust = false); /// Set camera distance for current mode. Don't work on 1st person view. /// \param adjust Indicates should distance be adjusted or set. diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 0c6e48645..d7549fc54 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1340,7 +1340,7 @@ namespace MWRender if(mCamera->isNearest() && dist > 0.f) mCamera->toggleViewMode(); else if (override) - mCamera->setBaseCameraDistance(-dist / 120.f * 10, adjust); + mCamera->updateBaseCameraDistance(-dist / 120.f * 10, adjust); else mCamera->setCameraDistance(-dist / 120.f * 10, adjust); } @@ -1348,7 +1348,7 @@ namespace MWRender { mCamera->toggleViewMode(); if (override) - mCamera->setBaseCameraDistance(0.f, false); + mCamera->updateBaseCameraDistance(0.f, false); else mCamera->setCameraDistance(0.f, false); } @@ -1397,7 +1397,7 @@ namespace MWRender void RenderingManager::changeVanityModeScale(float factor) { if(mCamera->isVanityOrPreviewModeEnabled()) - mCamera->setBaseCameraDistance(-factor/120.f*10, true); + mCamera->updateBaseCameraDistance(-factor/120.f*10, true); } void RenderingManager::overrideFieldOfView(float val) diff --git a/docs/source/reference/modding/settings/camera.rst b/docs/source/reference/modding/settings/camera.rst index ecc1bda50..20349e97f 100644 --- a/docs/source/reference/modding/settings/camera.rst +++ b/docs/source/reference/modding/settings/camera.rst @@ -114,6 +114,17 @@ while small values can result in the hands not being visible. This setting can only be configured by editing the settings configuration file. +third person camera distance +---------------------------- + +:Type: floating point +:Range: 30-800 +:Default: 192.0 + +Distance from the camera to the character in third person mode. + +This setting can be changed in game using "Zoom In" / "Zoom Out" controls. + view over shoulder ------------------ diff --git a/files/settings-default.cfg b/files/settings-default.cfg index b044bdd5c..1e62ff5bf 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -33,6 +33,9 @@ field of view = 60.0 # Best to leave this at the default since vanilla assets are not complete enough to adapt to high FoV's. Too low FoV would clip the hands off screen. first person field of view = 60.0 +# Distance from the camera to the character in third person mode. +third person camera distance = 192 + # If enabled then third person camera is positioned above character's shoulder and crosshair is visible. view over shoulder = false From fd61ebf6abf6e2077e0e0d23f7ab451e37823b3c Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Fri, 10 Jul 2020 00:44:54 +0200 Subject: [PATCH 27/33] remove big white blob of space --- apps/openmw/mwrender/renderingmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a7d9003dc..9876fae54 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1517,7 +1517,7 @@ namespace MWRender { if (!ptr.isInCell() || !ptr.getCell()->isExterior() || !mObjectPaging) return false; - if (mObjectPaging->enableObject(type, ptr.getCellRef().getRefNum(), ptr.getCellRef().getPosition().asVec3(), osg::Vec2i(ptr.getCell()->getCell()->getGridX(), ptr.getCell()->getCell()->getGridY()), enabled)) + if (mObjectPaging->enableObject(type, ptr.getCellRef().getRefNum(), ptr.getCellRef().getPosition().asVec3(), osg::Vec2i(ptr.getCell()->getCell()->getGridX(), ptr.getCell()->getCell()->getGridY()), enabled)) { mTerrain->rebuildViews(); return true; From 721e659d3757ad2458ad6a401d5daecf22e8a78d Mon Sep 17 00:00:00 2001 From: psi29a Date: Fri, 10 Jul 2020 12:12:07 +0000 Subject: [PATCH 28/33] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2f05c3c3..7be9cc2c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Bug #5367: Selecting a spell on an enchanted item per hotkey always plays the equip sound Bug #5369: Spawnpoint in the Grazelands doesn't produce oversized creatures Bug #5370: Opening an unlocked but trapped door uses the key + Bug #5384: openmw-cs: deleting an instance requires reload of scene window to show in editor Bug #5397: NPC greeting does not reset if you leave + reenter area Bug #5400: Editor: Verifier checks race of non-skin bodyparts Bug #5403: Enchantment effect doesn't show on an enemy during death animation From 5c3496fb15db92dffc30d4457f5347e5a91a4ac0 Mon Sep 17 00:00:00 2001 From: psi29a Date: Fri, 10 Jul 2020 12:22:58 +0000 Subject: [PATCH 29/33] Delete FindBullet.cmake; we use cmake's version which has been available since 3.0.2 and we have a requirement of 3.1.0 https://cmake.org/cmake/help/v3.0/module/FindBullet.html --- cmake/FindBullet.cmake | 73 ------------------------------------------ 1 file changed, 73 deletions(-) delete mode 100644 cmake/FindBullet.cmake diff --git a/cmake/FindBullet.cmake b/cmake/FindBullet.cmake deleted file mode 100644 index 6d68bed70..000000000 --- a/cmake/FindBullet.cmake +++ /dev/null @@ -1,73 +0,0 @@ -# - Try to find the Bullet physics engine -# -# This module accepts the following env variables -# BULLET_ROOT - Can be set to bullet install path or Windows build path -# -# Once done this will define -# Bullet_FOUND - System has the all required components. -# Bullet_INCLUDE_DIRS - Include directory necessary for using the required components headers. -# Bullet_LIBRARIES - Link these to use the required bullet components. -# Bullet_VERSION - Version of libbullet -# -# For each of the components -# - LinearMath -# - BulletCollision -# - BulletSoftBody -# - BulletDynamics -# -# Copyright (c) 2009, Philip Lowman -# Modified for OpenMW to parse BT_BULLET_VERSION. -# -# Redistribution AND use is allowed according to the terms of the New -# BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(LibFindMacros) - -# Macro: _internal_find_bullet_library -# Checks for the given component by invoking pkgconfig etc. -macro(_internal_find_bullet_library _lib) - libfind_pkg_detect(Bullet_${_lib} bullet - FIND_LIBRARY ${_lib} - HINTS $ENV{BULLET_ROOT} - PATH_SUFFIXES lib - ) - libfind_process(Bullet_${_lib}) -endmacro() - -set(_known_components LinearMath BulletCollision BulletSoftBody BulletDynamics) - -# Check if the required components were found and add their stuff to the Bullet_* vars. -foreach (_component ${Bullet_FIND_COMPONENTS}) - list(FIND _known_components ${_component} _known_component) - if (_known_component EQUAL -1) - message(FATAL_ERROR "Unknown component '${_component}'") - endif() - - set(Bullet_${_component}_Debug_FIND_QUIETLY TRUE) # don't spam messages with optional Debug component - _internal_find_bullet_library(${_component}) - _internal_find_bullet_library(${_component}_Debug) - - if (Bullet_${_component}_Debug_FOUND) - set(Bullet_LIBRARIES ${Bullet_LIBRARIES} optimized ${Bullet_${_component}_LIBRARIES} debug ${Bullet_${_component}_Debug_LIBRARIES}) - else() - set(Bullet_LIBRARIES ${Bullet_LIBRARIES} ${Bullet_${_component}_LIBRARIES}) - endif() -endforeach() - -libfind_pkg_detect(Bullet bullet - FIND_PATH btBulletCollisionCommon.h - HINTS $ENV{BULLET_ROOT} - PATH_SUFFIXES include/bullet -) -set(Bullet_INCLUDE_DIRS ${Bullet_INCLUDE_DIR}) -libfind_version_header(Bullet LinearMath/btScalar.h BT_BULLET_VERSION) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Bullet - FOUND_VAR Bullet_FOUND - VERSION_VAR Bullet_VERSION - HANDLE_COMPONENTS - REQUIRED_VARS - Bullet_LIBRARIES - Bullet_INCLUDE_DIR -) From 7300496a5fc32804fefd4c72072f51afce5f13f4 Mon Sep 17 00:00:00 2001 From: psi29a Date: Fri, 10 Jul 2020 12:27:22 +0000 Subject: [PATCH 30/33] Delete FindFreetype.cmake; as it is provided by cmake as of 3.0.2 and we require 3.1.0. --- cmake/FindFreetype.cmake | 91 ---------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 cmake/FindFreetype.cmake diff --git a/cmake/FindFreetype.cmake b/cmake/FindFreetype.cmake deleted file mode 100644 index 3b7586835..000000000 --- a/cmake/FindFreetype.cmake +++ /dev/null @@ -1,91 +0,0 @@ -#------------------------------------------------------------------- -# This file is part of the CMake build system for OGRE -# (Object-oriented Graphics Rendering Engine) -# For the latest info, see https://www.ogre3d.org/ -# -# The contents of this file are placed in the public domain. Feel -# free to make use of it in any way you like. -#------------------------------------------------------------------- - -# - Try to find FreeType -# -# This module accepts the following env variable -# FREETYPE_DIR - Can be set to custom install path -# -# Once done, this will define -# -# Freetype_FOUND - system has FreeType -# Freetype_INCLUDE_DIRS - the FreeType include directories -# Freetype_LIBRARIES - link these to use FreeType -# Freetype_VERSION - version of FreeType -# -# libfreetype internals: -# -# ====================================== -# new versions (2.5.2) -# -# file structure: -# /include/freetype2/ft2build.h -# /include/freetype2/freetype.h -# used as: -# #include -# #include -# requires: -# -I /include/freetype2/ -# -# ====================================== -# old versions (2.4.8, 2.3.5) -# -# file structure: -# /include/ft2build.h -# /include/freetype2/freetype/freetype.h -# used as: -# #include -# #include -# requires: -# -I /include/ -I /include/freetype2/ -# -# ====================================== - -include(LibFindMacros) - -set(_REGULAR_INSTALL_PATHS - /usr/X11R6 - /usr/local/X11R6 - /usr/local/X11 - /usr/freeware - ENV GTKMM_BASEPATH - [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path] -) - -libfind_pkg_detect(Freetype freetype2 - FIND_PATH ft2build.h - HINTS $ENV{FREETYPE_DIR} - PATHS ${_REGULAR_INSTALL_PATHS} - PATH_SUFFIXES include freetype2 - FIND_LIBRARY freetype freetype2311 freetype239 freetype238 freetype235 freetype219 - HINTS $ENV{FREETYPE_DIR} - PATHS ${_REGULAR_INSTALL_PATHS} - PATH_SUFFIXES lib -) -find_path(Freetype_OLD_INCLUDE_DIR - # in new versions of freetype old_include_dir equals to include_dir - # see explanation above - NAMES freetype/freetype.h freetype.h - PATHS ${Freetype_INCLUDE_DIR} - PATH_SUFFIXES freetype2 - NO_DEFAULT_PATH -) -libfind_version_n_header(Freetype - NAMES freetype/freetype.h freetype.h - PATHS Freetype_OLD_INCLUDE_DIR - DEFINES FREETYPE_MAJOR FREETYPE_MINOR FREETYPE_PATCH -) - -set(Freetype_PROCESS_INCLUDES Freetype_OLD_INCLUDE_DIR) -libfind_process(Freetype) - -if (Freetype_INCLUDE_DIRS) - list(REMOVE_DUPLICATES Freetype_INCLUDE_DIRS) -endif() From f47d2bb8afbcdd5eb838812c4a4c7ccc49a5c4fb Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Fri, 10 Jul 2020 15:01:44 +0200 Subject: [PATCH 31/33] make sure we use case-sensative BULLET_ prefix --- CMakeLists.txt | 2 +- components/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c5bf22fd..dbe28fd84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,7 +311,7 @@ include_directories("." ${Boost_INCLUDE_DIR} ${MyGUI_INCLUDE_DIRS} ${OPENAL_INCLUDE_DIR} - ${Bullet_INCLUDE_DIRS} + ${BULLET_INCLUDE_DIRS} ) link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS}) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 1d4a84ce1..86d657792 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -210,7 +210,7 @@ if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() endif () -include_directories(${Bullet_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) @@ -229,7 +229,7 @@ target_link_libraries(components ${OSGGA_LIBRARIES} ${OSGSHADOW_LIBRARIES} ${OSGANIMATION_LIBRARIES} - ${Bullet_LIBRARIES} + ${BULLET_LIBRARIES} ${SDL2_LIBRARIES} ${OPENGL_gl_LIBRARY} ${MyGUI_LIBRARIES} From 4a17bf27a368720bd141ca38f791190f307105f1 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sat, 11 Jul 2020 00:18:14 +0200 Subject: [PATCH 32/33] Set BULLET_ROOT via add_cmake_opts like we do the rest --- CI/before_script.msvc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 9a213963e..dc6eb7e44 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -606,7 +606,7 @@ printf "Bullet 2.89 (${BULLET_DBL_DISPLAY})... " eval 7z x -y "${DEPS}/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z" $STRIP mv "Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}" Bullet fi - export BULLET_ROOT="$(real_pwd)/Bullet" + add_cmake_opts -DBULLET_ROOT="$(real_pwd)/Bullet" echo Done. } cd $DEPS From a4e3f32ec89ab7364acf0e2d692fe83f0fe4a8a6 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 11 Jul 2020 13:29:20 +0200 Subject: [PATCH 33/33] Fix TSAN warnings for ripples emitter While main thread creates particles rendering thread draws them so sychronization is required. --- apps/openmw/mwrender/ripplesimulation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index f7feb267a..6788f53f4 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -200,6 +200,7 @@ void RippleSimulation::emitRipple(const osg::Vec3f &pos) { if (std::abs(pos.z() - mParticleNode->getPosition().z()) < 20) { + osgParticle::ParticleSystem::ScopedWriteLock lock(*mParticleSystem->getReadWriteMutex()); osgParticle::Particle* p = mParticleSystem->createParticle(nullptr); p->setPosition(osg::Vec3f(pos.x(), pos.y(), 0.f)); p->setAngle(osg::Vec3f(0,0, Misc::Rng::rollProbability() * osg::PI * 2 - osg::PI));