1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-28 19:21:04 +00:00

Embed error marker in osgt format inside a string defined in misc/errorMarker.hpp.

Use the embed error marker we fail to load a mesh.
This commit is contained in:
Cédric Mocquillon 2021-11-12 11:08:17 +01:00
parent 4d09f791ab
commit 40656b3135
4 changed files with 1438 additions and 29 deletions

View File

@ -93,7 +93,7 @@ add_component_dir (esmterrain
add_component_dir (misc add_component_dir (misc
constants utf8stream stringops resourcehelpers rng messageformatparser weakcache thread constants utf8stream stringops resourcehelpers rng messageformatparser weakcache thread
compression osguservalues compression osguservalues errorMarker
) )
add_component_dir (debug add_component_dir (debug

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
#ifndef OPENMW_COMPONENTS_MISC_ERRORMARKER_H
#define OPENMW_COMPONENTS_MISC_ERRORMARKER_H
#include <string>
namespace Misc
{
extern const std::string errorMarker;
}
#endif

View File

@ -21,6 +21,7 @@
#include <components/misc/pathhelpers.hpp> #include <components/misc/pathhelpers.hpp>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include <components/misc/algorithm.hpp> #include <components/misc/algorithm.hpp>
#include <components/misc/errorMarker.hpp>
#include <components/misc/osguservalues.hpp> #include <components/misc/osguservalues.hpp>
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
@ -36,6 +37,7 @@
#include <components/shader/shadermanager.hpp> #include <components/shader/shadermanager.hpp>
#include <components/files/hash.hpp> #include <components/files/hash.hpp>
#include <components/files/memorystream.hpp>
#include "imagemanager.hpp" #include "imagemanager.hpp"
#include "niffilemanager.hpp" #include "niffilemanager.hpp"
@ -483,13 +485,11 @@ namespace Resource
Resource::ImageManager* mImageManager; Resource::ImageManager* mImageManager;
}; };
osg::ref_ptr<osg::Node> load (const std::string& normalizedFilename, const VFS::Manager* vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager) namespace
{ {
auto ext = Misc::getFileExtension(normalizedFilename); osg::ref_ptr<osg::Node> loadNonNif(const std::string& normalizedFilename, std::istream& model, Resource::ImageManager* imageManager)
if (ext == "nif")
return NifOsg::Loader::load(nifFileManager->get(normalizedFilename), imageManager);
else
{ {
auto ext = Misc::getFileExtension(normalizedFilename);
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension(std::string(ext)); osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension(std::string(ext));
if (!reader) if (!reader)
{ {
@ -505,10 +505,9 @@ namespace Resource
options->setReadFileCallback(new ImageReadCallback(imageManager)); options->setReadFileCallback(new ImageReadCallback(imageManager));
if (ext == "dae") options->setOptionString("daeUseSequencedTextureUnits"); if (ext == "dae") options->setOptionString("daeUseSequencedTextureUnits");
Files::IStreamPtr stream = vfs->get(normalizedFilename); const std::uint64_t fileHash = Files::getHash(normalizedFilename, model);
const std::uint64_t fileHash = Files::getHash(normalizedFilename, *stream);
osgDB::ReaderWriter::ReadResult result = reader->readNode(*stream, options); osgDB::ReaderWriter::ReadResult result = reader->readNode(model, options);
if (!result.success()) if (!result.success())
{ {
std::stringstream errormsg; std::stringstream errormsg;
@ -519,7 +518,9 @@ namespace Resource
// Recognize and hide collision node // Recognize and hide collision node
unsigned int hiddenNodeMask = 0; unsigned int hiddenNodeMask = 0;
SceneUtil::FindByNameVisitor nameFinder("Collision"); SceneUtil::FindByNameVisitor nameFinder("Collision");
result.getNode()->accept(nameFinder);
auto node = result.getNode();
node->accept(nameFinder);
if (nameFinder.mFoundNode) if (nameFinder.mFoundNode)
nameFinder.mFoundNode->setNodeMask(hiddenNodeMask); nameFinder.mFoundNode->setNodeMask(hiddenNodeMask);
@ -527,16 +528,14 @@ namespace Resource
{ {
// Collada alpha testing // Collada alpha testing
Resource::ColladaAlphaTrickVisitor colladaAlphaTrickVisitor; Resource::ColladaAlphaTrickVisitor colladaAlphaTrickVisitor;
result.getNode()->accept(colladaAlphaTrickVisitor); node->accept(colladaAlphaTrickVisitor);
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f)); node->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f));
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("specStrength", 1.f)); node->getOrCreateStateSet()->addUniform(new osg::Uniform("specStrength", 1.f));
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1))); node->getOrCreateStateSet()->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1)));
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("useFalloff", false)); node->getOrCreateStateSet()->addUniform(new osg::Uniform("useFalloff", false));
} }
auto node = result.getNode();
node->setUserValue(Misc::OsgUserValues::sFileHash, node->setUserValue(Misc::OsgUserValues::sFileHash,
std::string(reinterpret_cast<const char*>(&fileHash), sizeof(fileHash))); std::string(reinterpret_cast<const char*>(&fileHash), sizeof(fileHash)));
@ -544,6 +543,15 @@ namespace Resource
} }
} }
osg::ref_ptr<osg::Node> load (const std::string& normalizedFilename, const VFS::Manager* vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager)
{
auto ext = Misc::getFileExtension(normalizedFilename);
if (ext == "nif")
return NifOsg::Loader::load(nifFileManager->get(normalizedFilename), imageManager);
else
return loadNonNif(normalizedFilename, *vfs->get(normalizedFilename), imageManager);
}
class CanOptimizeCallback : public SceneUtil::Optimizer::IsOperationPermissibleForObjectCallback class CanOptimizeCallback : public SceneUtil::Optimizer::IsOperationPermissibleForObjectCallback
{ {
public: public:
@ -659,23 +667,23 @@ namespace Resource
{ {
loaded = load(normalized, mVFS, mImageManager, mNifFileManager); loaded = load(normalized, mVFS, mImageManager, mNifFileManager);
} }
catch (std::exception& e) catch (const std::exception& e)
{ {
static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2", "dae" }; static osg::ref_ptr<osg::Node> 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) for (unsigned int i=0; i<sizeof(sMeshTypes)/sizeof(sMeshTypes[0]); ++i)
{
normalized = "meshes/marker_error." + std::string(sMeshTypes[i]);
if (mVFS->exists(normalized))
{ {
Log(Debug::Error) << "Failed to load '" << name << "': " << e.what() << ", using marker_error." << sMeshTypes[i] << " instead"; normalized = "meshes/marker_error." + std::string(sMeshTypes[i]);
loaded = load(normalized, mVFS, mImageManager, mNifFileManager); if (mVFS->exists(normalized))
break; return load(normalized, mVFS, mImageManager, mNifFileManager);
} }
} Files::IMemStream file(Misc::errorMarker.data(), Misc::errorMarker.size());
return loadNonNif("error_marker.osgt", file, mImageManager);
}();
if (!loaded) Log(Debug::Error) << "Failed to load '" << name << "': " << e.what() << ", using marker_error instead";
throw; loaded = static_cast<osg::Node*>(errorMarkerNode->clone(osg::CopyOp::DEEP_COPY_ALL));
} }
// set filtering settings // set filtering settings