1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-30 08:15:37 +00:00

Merge branch 'bullet_shape_hash' into 'master'

Store BulletShape source file name and content hash

See merge request OpenMW/openmw!1379
This commit is contained in:
psi29a 2021-11-13 13:33:22 +00:00
commit 41bd20e358
14 changed files with 130 additions and 4 deletions

View file

@ -335,6 +335,7 @@ namespace
MOCK_METHOD(void, setUseSkinning, (bool), (override));
MOCK_METHOD(bool, getUseSkinning, (), (const, override));
MOCK_METHOD(std::string, getFilename, (), (const, override));
MOCK_METHOD(std::uint64_t, getHash, (), (const, override));
MOCK_METHOD(unsigned int, getVersion, (), (const, override));
MOCK_METHOD(unsigned int, getUserVersion, (), (const, override));
MOCK_METHOD(unsigned int, getBethVersion, (), (const, override));
@ -381,6 +382,7 @@ namespace
),
btVector3(4, 8, 12)
};
const std::uint64_t mHash = 42;
TestBulletNifLoader()
{
@ -411,6 +413,8 @@ namespace
mNiTriStripsData.vertices = {osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0), osg::Vec3f(0, 1, 0)};
mNiTriStripsData.strips = {{0, 1, 2, 3}};
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
EXPECT_CALL(mNifFile, getHash()).WillOnce(Return(mHash));
}
};
@ -423,6 +427,8 @@ namespace
Resource::BulletShape expected;
EXPECT_EQ(*result, expected);
EXPECT_EQ(result->mFileName, "test.nif");
EXPECT_EQ(result->mFileHash, mHash);
}
TEST_F(TestBulletNifLoader, should_ignore_nullptr_root)

View file

@ -93,7 +93,7 @@ add_component_dir (esmterrain
add_component_dir (misc
constants utf8stream stringops resourcehelpers rng messageformatparser weakcache thread
compression
compression osguservalues
)
add_component_dir (debug
@ -106,7 +106,7 @@ IF(NOT WIN32 AND NOT APPLE)
ENDIF()
add_component_dir (files
linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager escape
lowlevelfile constrainedfilestream memorystream
lowlevelfile constrainedfilestream memorystream hash
)
add_component_dir (compiler

36
components/files/hash.cpp Normal file
View file

@ -0,0 +1,36 @@
#include "hash.hpp"
#include <components/misc/hash.hpp>
#include <cstdint>
#include <functional>
#include <istream>
#include <string>
namespace Files
{
std::uint64_t getHash(const std::string& fileName, std::istream& stream)
{
std::uint64_t hash = std::hash<std::string> {}(fileName);
try
{
const auto start = stream.tellg();
const auto exceptions = stream.exceptions();
stream.exceptions(std::ios_base::badbit);
while (stream)
{
std::uint64_t value = 0;
stream.read(reinterpret_cast<char*>(&value), sizeof(value));
Misc::hashCombine(hash, value);
}
stream.exceptions(exceptions);
stream.clear();
stream.seekg(start);
}
catch (const std::exception& e)
{
throw std::runtime_error("Error while reading \"" + fileName + "\" to get hash: " + std::string(e.what()));
}
return hash;
}
}

13
components/files/hash.hpp Normal file
View file

@ -0,0 +1,13 @@
#ifndef COMPONENTS_FILES_HASH_H
#define COMPONENTS_FILES_HASH_H
#include <cstdint>
#include <istream>
#include <string>
namespace Files
{
std::uint64_t getHash(const std::string& fileName, std::istream& stream);
}
#endif

View file

@ -0,0 +1,6 @@
#include "osguservalues.hpp"
namespace Misc
{
const std::string OsgUserValues::sFileHash = "fileHash";
}

View file

@ -0,0 +1,14 @@
#ifndef OPENMW_COMPONENTS_MISC_OSGUSERVALUES_H
#define OPENMW_COMPONENTS_MISC_OSGUSERVALUES_H
#include <string>
namespace Misc
{
struct OsgUserValues
{
static const std::string sFileHash;
};
}
#endif

View file

@ -1,6 +1,8 @@
#include "niffile.hpp"
#include "effect.hpp"
#include <components/files/hash.hpp>
#include <array>
#include <map>
#include <sstream>
@ -161,6 +163,8 @@ std::string NIFFile::printVersion(unsigned int version)
void NIFFile::parse(Files::IStreamPtr stream)
{
hash = Files::getHash(filename, *stream);
NIFStream nif (this, stream);
// Check the header string

View file

@ -34,6 +34,8 @@ struct File
virtual std::string getFilename() const = 0;
virtual std::uint64_t getHash() const = 0;
virtual unsigned int getVersion() const = 0;
virtual unsigned int getUserVersion() const = 0;
@ -50,6 +52,7 @@ class NIFFile final : public File
/// File name, used for error messages and opening the file
std::string filename;
std::uint64_t hash = 0;
/// Record list
std::vector<Record*> records;
@ -141,6 +144,8 @@ public:
/// Get the name of the file
std::string getFilename() const override { return filename; }
std::uint64_t getHash() const override { return hash; }
/// Get the version of the NIF format used
unsigned int getVersion() const override { return ver; }

View file

@ -166,6 +166,8 @@ osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif)
mStaticMesh.reset();
mAvoidStaticMesh.reset();
mShape->mFileHash = nif.getHash();
const size_t numRoots = nif.numRoots();
std::vector<const Nif::Node*> roots;
for (size_t i = 0; i < numRoots; ++i)
@ -178,6 +180,7 @@ osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif)
roots.emplace_back(node);
}
const std::string filename = nif.getFilename();
mShape->mFileName = filename;
if (roots.empty())
{
warn("Found no root nodes in NIF file " + filename);

View file

@ -17,6 +17,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/imagemanager.hpp>
#include <components/sceneutil/util.hpp>
#include <components/misc/osguservalues.hpp>
// particle
#include <osgParticle/ParticleSystem>
@ -325,6 +326,10 @@ namespace NifOsg
if (!textkeys->mTextKeys.empty())
created->getOrCreateUserDataContainer()->addUserObject(textkeys);
const std::uint64_t nifHash = nif->getHash();
created->setUserValue(Misc::OsgUserValues::sFileHash,
std::string(reinterpret_cast<const char*>(&nifHash), sizeof(nifHash)));
return created;
}

View file

@ -74,6 +74,8 @@ BulletShape::BulletShape(const BulletShape &copy, const osg::CopyOp &copyop)
, mAvoidCollisionShape(duplicateCollisionShape(copy.mAvoidCollisionShape.get()))
, mCollisionBox(copy.mCollisionBox)
, mAnimatedShapes(copy.mAnimatedShapes)
, mFileName(copy.mFileName)
, mFileHash(copy.mFileHash)
{
}

View file

@ -12,6 +12,11 @@
class btCollisionShape;
namespace NifBullet
{
class BulletNifLoader;
}
namespace Resource
{
struct DeleteCollisionShape
@ -47,6 +52,9 @@ namespace Resource
// we store the node's record index mapped to the child index of the shape in the btCompoundShape.
std::map<int, int> mAnimatedShapes;
std::string mFileName;
std::uint64_t mFileHash = 0;
void setLocalScaling(const btVector3& scale);
bool isAnimated() const { return !mAnimatedShapes.empty(); }
@ -60,6 +68,8 @@ namespace Resource
public:
BulletShapeInstance(osg::ref_ptr<const BulletShape> source);
const osg::ref_ptr<const BulletShape>& getSource() const { return mSource; }
private:
osg::ref_ptr<const BulletShape> mSource;
};

View file

@ -1,5 +1,7 @@
#include "bulletshapemanager.hpp"
#include <cstring>
#include <osg/NodeVisitor>
#include <osg/TriangleFunctor>
#include <osg/Transform>
@ -10,6 +12,7 @@
#include <components/misc/pathhelpers.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/vfs/manager.hpp>
#include <components/misc/osguservalues.hpp>
#include <components/nifbullet/bulletnifloader.hpp>
@ -162,6 +165,15 @@ osg::ref_ptr<const BulletShape> BulletShapeManager::getShape(const std::string &
if (!shape)
return osg::ref_ptr<BulletShape>();
}
if (shape != nullptr)
{
shape->mFileName = normalized;
std::string fileHash;
constNode->getUserValue(Misc::OsgUserValues::sFileHash, fileHash);
if (!fileHash.empty())
std::memcpy(&shape->mFileHash, fileHash.data(), std::min(fileHash.size(), sizeof(shape->mFileHash)));
}
}
mCache->addEntryToObjectCache(normalized, shape);

View file

@ -21,6 +21,7 @@
#include <components/misc/pathhelpers.hpp>
#include <components/misc/stringops.hpp>
#include <components/misc/algorithm.hpp>
#include <components/misc/osguservalues.hpp>
#include <components/vfs/manager.hpp>
@ -34,6 +35,8 @@
#include <components/shader/shadervisitor.hpp>
#include <components/shader/shadermanager.hpp>
#include <components/files/hash.hpp>
#include "imagemanager.hpp"
#include "niffilemanager.hpp"
#include "objectcache.hpp"
@ -502,7 +505,10 @@ namespace Resource
options->setReadFileCallback(new ImageReadCallback(imageManager));
if (ext == "dae") options->setOptionString("daeUseSequencedTextureUnits");
osgDB::ReaderWriter::ReadResult result = reader->readNode(*vfs->get(normalizedFilename), options);
Files::IStreamPtr stream = vfs->get(normalizedFilename);
const std::uint64_t fileHash = Files::getHash(normalizedFilename, *stream);
osgDB::ReaderWriter::ReadResult result = reader->readNode(*stream, options);
if (!result.success())
{
std::stringstream errormsg;
@ -529,8 +535,12 @@ namespace Resource
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("useFalloff", false));
}
auto node = result.getNode();
return result.getNode();
node->setUserValue(Misc::OsgUserValues::sFileHash,
std::string(reinterpret_cast<const char*>(&fileHash), sizeof(fileHash)));
return node;
}
}