From 97c42768e67424790114954c77a0617ca8f1e04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mocquillon?= Date: Sun, 19 Feb 2023 17:58:04 +0100 Subject: [PATCH 1/2] Use the embedded marker error if we fail to load the error marker model from the vfs --- CHANGELOG.md | 1 + components/resource/scenemanager.cpp | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b42b6471a6..8c63325560 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,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..aff31f8c5c 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -852,12 +852,24 @@ namespace Resource { 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) + static bool useEmbedded = false; + if (!useEmbedded) { - normalized = "meshes/marker_error." + std::string(sMeshTypes[i]); - if (mVFS->exists(normalized)) - return load(normalized, mVFS, mImageManager, mNifFileManager); + try + { + 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); + } + } + catch (const std::exception& e) + { + useEmbedded = true; + 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); From f7b45a6262c32a38b03d2b3d742cbc64713bb235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mocquillon?= Date: Tue, 21 Feb 2023 13:25:18 +0100 Subject: [PATCH 2/2] Add method to load and clone the error marker used by the scene manager --- components/resource/scenemanager.cpp | 55 +++++++++++++++------------- components/resource/scenemanager.hpp | 3 ++ 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index aff31f8c5c..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,33 +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" }; - static bool useEmbedded = false; - if (!useEmbedded) - { - try - { - 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); - } - } - catch (const std::exception& e) - { - useEmbedded = true; - 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); - }(); - 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&);