diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ce7fe801a..77bc52ec3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Bug #7122: Teleportation to underwater should cancel active water walking effect Bug #7163: Myar Aranath: Wheat breaks the GUI Bug #7172: Current music playlist continues playing indefinitely if next playlist is empty + Bug #7229: Error marker loading failure is not handled Bug #7243: Get Skyrim.esm loading Feature #5492: Let rain and snow collide with statics Feature #6447: Add LOD support to Object Paging diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index b6a22c08a4..4184786aea 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -831,6 +831,34 @@ namespace Resource mSharedStateMutex.unlock(); } + osg::ref_ptr SceneManager::loadErrorMarker() + { + try + { + for (const auto meshType : { "nif", "osg", "osgt", "osgb", "osgx", "osg2", "dae" }) + { + const std::string normalized = "meshes/marker_error." + std::string(meshType); + if (mVFS->exists(normalized)) + return load(normalized, mVFS, mImageManager, mNifFileManager); + } + } + catch (const std::exception& e) + { + Log(Debug::Warning) << "Failed to load error marker:" << e.what() + << ", using embedded marker_error instead"; + } + Files::IMemStream file(ErrorMarker::sValue.data(), ErrorMarker::sValue.size()); + return loadNonNif("error_marker.osgt", file, mImageManager); + } + + osg::ref_ptr SceneManager::cloneErrorMarker() + { + if (!mErrorMarker) + mErrorMarker = loadErrorMarker(); + + return static_cast(mErrorMarker->clone(osg::CopyOp::DEEP_COPY_ALL)); + } + osg::ref_ptr SceneManager::getTemplate(const std::string& name, bool compile) { std::string normalized = mVFS->normalizeFilename(name); @@ -850,21 +878,8 @@ namespace Resource } catch (const std::exception& e) { - static osg::ref_ptr errorMarkerNode = [&] { - static const char* const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2", "dae" }; - - for (unsigned int i = 0; i < sizeof(sMeshTypes) / sizeof(sMeshTypes[0]); ++i) - { - normalized = "meshes/marker_error." + std::string(sMeshTypes[i]); - if (mVFS->exists(normalized)) - return load(normalized, mVFS, mImageManager, mNifFileManager); - } - Files::IMemStream file(ErrorMarker::sValue.data(), ErrorMarker::sValue.size()); - return loadNonNif("error_marker.osgt", file, mImageManager); - }(); - Log(Debug::Error) << "Failed to load '" << name << "': " << e.what() << ", using marker_error instead"; - loaded = static_cast(errorMarkerNode->clone(osg::CopyOp::DEEP_COPY_ALL)); + loaded = cloneErrorMarker(); } // set filtering settings diff --git a/components/resource/scenemanager.hpp b/components/resource/scenemanager.hpp index 9b77e742df..3648cdfa27 100644 --- a/components/resource/scenemanager.hpp +++ b/components/resource/scenemanager.hpp @@ -228,6 +228,8 @@ namespace Resource private: Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects"); + osg::ref_ptr loadErrorMarker(); + osg::ref_ptr cloneErrorMarker(); std::unique_ptr mShaderManager; bool mForceShaders; @@ -260,6 +262,7 @@ namespace Resource osg::ref_ptr mIncrementalCompileOperation; unsigned int mParticleSystemMask; + mutable osg::ref_ptr mErrorMarker; SceneManager(const SceneManager&); void operator=(const SceneManager&);