1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-04-26 12:36:48 +00:00

Separate NIFFileReader from NIFFile

NIFFile might not always be created from a file or stream containing NIF data.
Basically there are 2 different responsibilities for this class:
1. Read NIF file
2. Provide input for nifosg and bulletnifloader.

Remove no longer needed NIFFileMock since the state of NIFFfile can be
initialized independently from reading NIF file.
This commit is contained in:
elsid 2022-09-17 19:24:42 +02:00
parent b39ccbeeef
commit f2fb3d6de8
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
31 changed files with 446 additions and 420 deletions

View file

@ -50,7 +50,9 @@ void readVFS(std::unique_ptr<VFS::Archive>&& anArchive, const std::filesystem::p
if (isNIF(name)) if (isNIF(name))
{ {
// std::cout << "Decoding: " << name << std::endl; // std::cout << "Decoding: " << name << std::endl;
Nif::NIFFile temp_nif(myManager.get(name), archivePath / name); Nif::NIFFile file(archivePath / name);
Nif::Reader reader(file);
reader.parse(myManager.get(name));
} }
else if (isBSA(name)) else if (isBSA(name))
{ {
@ -120,7 +122,7 @@ int main(int argc, char** argv)
if (!parseOptions(argc, argv, files)) if (!parseOptions(argc, argv, files))
return 1; return 1;
Nif::NIFFile::setLoadUnsupportedFiles(true); Nif::Reader::setLoadUnsupportedFiles(true);
// std::cout << "Reading Files" << std::endl; // std::cout << "Reading Files" << std::endl;
for (const auto& path : files) for (const auto& path : files)
{ {
@ -129,7 +131,9 @@ int main(int argc, char** argv)
if (isNIF(path)) if (isNIF(path))
{ {
// std::cout << "Decoding: " << name << std::endl; // std::cout << "Decoding: " << name << std::endl;
Nif::NIFFile temp_nif(Files::openConstrainedFileStream(path), path); Nif::NIFFile file(path);
Nif::Reader reader(file);
reader.parse(Files::openConstrainedFileStream(path));
} }
else if (isBSA(path)) else if (isBSA(path))
{ {

View file

@ -616,7 +616,7 @@ namespace MWRender
MWBase::Environment::get().getWindowManager()->setCullMask(mask); MWBase::Environment::get().getWindowManager()->setCullMask(mask);
NifOsg::Loader::setHiddenNodeMask(Mask_UpdateVisitor); NifOsg::Loader::setHiddenNodeMask(Mask_UpdateVisitor);
NifOsg::Loader::setIntersectionDisabledNodeMask(Mask_Effect); NifOsg::Loader::setIntersectionDisabledNodeMask(Mask_Effect);
Nif::NIFFile::setLoadUnsupportedFiles(Settings::Manager::getBool("load unsupported nif files", "Models")); Nif::Reader::setLoadUnsupportedFiles(Settings::Manager::getBool("load unsupported nif files", "Models"));
mStateUpdater->setFogEnd(mViewDistance); mStateUpdater->setFogEnd(mViewDistance);

View file

@ -333,31 +333,9 @@ namespace
dst.rotation.mValues[column][row] = src.getBasis().getRow(row)[column]; dst.rotation.mValues[column][row] = src.getBasis().getRow(row)[column];
} }
struct NifFileMock : Nif::File
{
MOCK_METHOD(Nif::Record*, getRecord, (std::size_t), (const, override));
MOCK_METHOD(std::size_t, numRecords, (), (const, override));
MOCK_METHOD(Nif::Record*, getRoot, (std::size_t), (const, override));
MOCK_METHOD(std::size_t, numRoots, (), (const, override));
MOCK_METHOD(std::string, getString, (uint32_t), (const, override));
MOCK_METHOD(void, setUseSkinning, (bool), (override));
MOCK_METHOD(bool, getUseSkinning, (), (const, override));
MOCK_METHOD(std::filesystem::path, getFilename, (), (const, override));
MOCK_METHOD(std::string, getHash, (), (const, override));
MOCK_METHOD(unsigned int, getVersion, (), (const, override));
MOCK_METHOD(unsigned int, getUserVersion, (), (const, override));
MOCK_METHOD(unsigned int, getBethVersion, (), (const, override));
};
struct RecordMock : Nif::Record
{
MOCK_METHOD(void, read, (Nif::NIFStream * nif), (override));
};
struct TestBulletNifLoader : Test struct TestBulletNifLoader : Test
{ {
BulletNifLoader mLoader; BulletNifLoader mLoader;
const StrictMock<const NifFileMock> mNifFile;
Nif::Node mNode; Nif::Node mNode;
Nif::Node mNode2; Nif::Node mNode2;
Nif::NiNode mNiNode; Nif::NiNode mNiNode;
@ -412,16 +390,15 @@ namespace
= { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0), osg::Vec3f(0, 1, 0) }; = { 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 } }; mNiTriStripsData.strips = { { 0, 1, 2, 3 } };
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriStripsData); mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
EXPECT_CALL(mNifFile, getHash()).WillOnce(Return(mHash));
} }
}; };
TEST_F(TestBulletNifLoader, for_zero_num_roots_should_return_default) TEST_F(TestBulletNifLoader, for_zero_num_roots_should_return_default)
{ {
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(0)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
@ -432,10 +409,11 @@ namespace
TEST_F(TestBulletNifLoader, should_ignore_nullptr_root) TEST_F(TestBulletNifLoader, should_ignore_nullptr_root)
{ {
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(nullptr)); file.mRoots.push_back(nullptr);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
@ -444,10 +422,11 @@ namespace
TEST_F(TestBulletNifLoader, for_default_root_nif_node_should_return_default) TEST_F(TestBulletNifLoader, for_default_root_nif_node_should_return_default)
{ {
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode)); file.mRoots.push_back(&mNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
@ -458,10 +437,11 @@ namespace
{ {
mNode.recType = Nif::RC_RootCollisionNode; mNode.recType = Nif::RC_RootCollisionNode;
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode)); file.mRoots.push_back(&mNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
@ -470,10 +450,11 @@ namespace
TEST_F(TestBulletNifLoader, for_default_root_nif_node_and_filename_starting_with_x_should_return_default) TEST_F(TestBulletNifLoader, for_default_root_nif_node_and_filename_starting_with_x_should_return_default)
{ {
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode)); file.mRoots.push_back(&mNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
@ -489,10 +470,11 @@ namespace
mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); mNode.bounds.box.extents = osg::Vec3f(1, 2, 3);
mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); mNode.bounds.box.center = osg::Vec3f(-1, -2, -3);
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode)); file.mRoots.push_back(&mNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3); expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3);
@ -515,10 +497,11 @@ namespace
mNode.parents.push_back(&mNiNode); mNode.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNode) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNode) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3); expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3);
@ -547,10 +530,11 @@ namespace
mNiNode.bounds.box.center = osg::Vec3f(-4, -5, -6); mNiNode.bounds.box.center = osg::Vec3f(-4, -5, -6);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNode) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNode) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3); expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3);
@ -585,10 +569,11 @@ namespace
mNiNode.bounds.box.center = osg::Vec3f(-7, -8, -9); mNiNode.bounds.box.center = osg::Vec3f(-7, -8, -9);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3); expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3);
@ -623,10 +608,11 @@ namespace
mNiNode.bounds.box.center = osg::Vec3f(-7, -8, -9); mNiNode.bounds.box.center = osg::Vec3f(-7, -8, -9);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
expected.mCollisionBox.mExtents = osg::Vec3f(4, 5, 6); expected.mCollisionBox.mExtents = osg::Vec3f(4, 5, 6);
@ -647,10 +633,11 @@ namespace
mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); mNode.bounds.box.extents = osg::Vec3f(1, 2, 3);
mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); mNode.bounds.box.center = osg::Vec3f(-1, -2, -3);
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode)); file.mRoots.push_back(&mNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3); expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3);
@ -661,10 +648,11 @@ namespace
TEST_F(TestBulletNifLoader, for_tri_shape_root_node_should_return_shape_with_triangle_mesh_shape) TEST_F(TestBulletNifLoader, for_tri_shape_root_node_should_return_shape_with_triangle_mesh_shape)
{ {
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriShape)); file.mRoots.push_back(&mNiTriShape);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -682,10 +670,11 @@ namespace
mNiTriShape.bounds.box.extents = osg::Vec3f(1, 2, 3); mNiTriShape.bounds.box.extents = osg::Vec3f(1, 2, 3);
mNiTriShape.bounds.box.center = osg::Vec3f(-1, -2, -3); mNiTriShape.bounds.box.center = osg::Vec3f(-1, -2, -3);
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriShape)); file.mRoots.push_back(&mNiTriShape);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3); expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3);
@ -699,10 +688,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -719,10 +709,11 @@ namespace
mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
mNiTriShape.parents.push_back(&mNiNode2); mNiTriShape.parents.push_back(&mNiNode2);
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -739,10 +730,11 @@ namespace
mNiNode.children mNiNode.children
= Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape), Nif::NodePtr(&mNiTriShape2) })); = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape), Nif::NodePtr(&mNiTriShape2) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1)); triangles->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1));
@ -760,10 +752,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -779,10 +772,11 @@ namespace
copy(mTransform, mNiTriShape.trafo); copy(mTransform, mNiTriShape.trafo);
mNiTriShape.trafo.scale = 3; mNiTriShape.trafo.scale = 3;
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriShape)); file.mRoots.push_back(&mNiTriShape);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -806,10 +800,11 @@ namespace
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
mNiNode.trafo.scale = 4; mNiNode.trafo.scale = 4;
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -840,10 +835,11 @@ namespace
Nif::NodePtr(&mNiTriShape2), Nif::NodePtr(&mNiTriShape2),
})); }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -876,10 +872,11 @@ namespace
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
mNiNode.trafo.scale = 4; mNiNode.trafo.scale = 4;
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -912,10 +909,11 @@ namespace
})); }));
mNiNode.trafo.scale = 4; mNiNode.trafo.scale = 4;
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle( triangles->addTriangle(
@ -943,11 +941,12 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(2)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getRoot(1)).WillOnce(Return(&mNiTriShape2)); file.mRoots.push_back(&mNiTriShape2);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -974,10 +973,11 @@ namespace
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
mNiNode.recType = Nif::RC_AvoidNode; mNiNode.recType = Nif::RC_AvoidNode;
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -993,10 +993,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
@ -1011,10 +1012,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
@ -1030,10 +1032,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -1054,10 +1057,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -1077,10 +1081,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -1101,10 +1106,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -1131,10 +1137,11 @@ namespace
mNiNode.children = Nif::NodeList( mNiNode.children = Nif::NodeList(
std::vector<Nif::NodePtr>({ Nif::NodePtr(&niTriShape), Nif::NodePtr(&emptyCollisionNode) })); std::vector<Nif::NodePtr>({ Nif::NodePtr(&niTriShape), Nif::NodePtr(&emptyCollisionNode) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -1154,10 +1161,11 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
Resource::BulletShape expected; Resource::BulletShape expected;
@ -1177,10 +1185,11 @@ namespace
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiNode2) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiNode2) }));
mNiNode.recType = Nif::RC_NiNode; mNiNode.recType = Nif::RC_NiNode;
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -1194,10 +1203,11 @@ namespace
{ {
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriStripsData); mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriShape)); file.mRoots.push_back(&mNiTriShape);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
const Resource::BulletShape expected; const Resource::BulletShape expected;
@ -1206,10 +1216,11 @@ namespace
TEST_F(TestBulletNifLoader, for_tri_strips_root_node_should_return_shape_with_triangle_mesh_shape) TEST_F(TestBulletNifLoader, for_tri_strips_root_node_should_return_shape_with_triangle_mesh_shape)
{ {
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriStrips)); file.mRoots.push_back(&mNiTriStrips);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -1224,10 +1235,11 @@ namespace
{ {
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriShapeData); mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriStrips)); file.mRoots.push_back(&mNiTriStrips);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
const Resource::BulletShape expected; const Resource::BulletShape expected;
@ -1238,10 +1250,11 @@ namespace
{ {
mNiTriStripsData.strips.clear(); mNiTriStripsData.strips.clear();
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriStrips)); file.mRoots.push_back(&mNiTriStrips);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
const Resource::BulletShape expected; const Resource::BulletShape expected;
@ -1252,10 +1265,11 @@ namespace
{ {
mNiTriStripsData.strips.front() = { 0, 1 }; mNiTriStripsData.strips.front() = { 0, 1 };
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriStrips)); file.mRoots.push_back(&mNiTriStrips);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
const Resource::BulletShape expected; const Resource::BulletShape expected;
@ -1269,10 +1283,11 @@ namespace
mNiNode.recType = Nif::RC_AvoidNode; mNiNode.recType = Nif::RC_AvoidNode;
mNiTriStripsData.strips.front() = { 0, 1 }; mNiTriStripsData.strips.front() = { 0, 1 };
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("test.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriStrips)); file.mRoots.push_back(&mNiTriStrips);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
const Resource::BulletShape expected; const Resource::BulletShape expected;
@ -1285,10 +1300,11 @@ namespace
mNiTriStrips.parents.push_back(&mNiNode); mNiTriStrips.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriStrips) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriStrips) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
const Resource::BulletShape expected; const Resource::BulletShape expected;
@ -1301,11 +1317,12 @@ namespace
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(2)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getRoot(1)).WillOnce(Return(&mNiTriStrips)); file.mRoots.push_back(&mNiTriStrips);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
@ -1330,11 +1347,12 @@ namespace
mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
mNiNode2.trafo.scale = 3; mNiNode2.trafo.scale = 3;
EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(2)); Nif::NIFFile file("xtest.nif");
EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); file.mRoots.push_back(&mNiNode);
EXPECT_CALL(mNifFile, getRoot(1)).WillOnce(Return(&mNiNode2)); file.mRoots.push_back(&mNiNode2);
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif")); file.mHash = mHash;
const auto result = mLoader.load(mNifFile);
const auto result = mLoader.load(file);
std::unique_ptr<btTriangleMesh> triangles1(new btTriangleMesh(false)); std::unique_ptr<btTriangleMesh> triangles1(new btTriangleMesh(false));
triangles1->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles1->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));

View file

@ -23,7 +23,7 @@ namespace Nif
controller.read(nif); controller.read(nif);
} }
void Named::post(NIFFile* nif) void Named::post(Reader& nif)
{ {
extra.post(nif); extra.post(nif);
extralist.post(nif); extralist.post(nif);

View file

@ -18,7 +18,7 @@ namespace Nif
unsigned int recordSize{ 0u }; unsigned int recordSize{ 0u };
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override { next.post(nif); } void post(Reader& nif) override { next.post(nif); }
}; };
struct Controller : public Record struct Controller : public Record
@ -43,7 +43,7 @@ namespace Nif
NamedPtr target; NamedPtr target;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
bool isActive() const { return flags & Flag_Active; } bool isActive() const { return flags & Flag_Active; }
ExtrapolationMode extrapolationMode() const { return static_cast<ExtrapolationMode>(flags & Mask); } ExtrapolationMode extrapolationMode() const { return static_cast<ExtrapolationMode>(flags & Mask); }
@ -58,7 +58,7 @@ namespace Nif
ControllerPtr controller; ControllerPtr controller;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
using NiSequenceStreamHelper = Named; using NiSequenceStreamHelper = Named;

View file

@ -42,7 +42,7 @@ namespace Nif
/* bool mPersistRenderData = */ nif->getBoolean(); /* bool mPersistRenderData = */ nif->getBoolean();
} }
void NiSourceTexture::post(NIFFile* nif) void NiSourceTexture::post(Reader& nif)
{ {
Named::post(nif); Named::post(nif);
data.post(nif); data.post(nif);
@ -59,7 +59,7 @@ namespace Nif
controller.read(nif); controller.read(nif);
} }
void NiParticleModifier::post(NIFFile* nif) void NiParticleModifier::post(Reader& nif)
{ {
next.post(nif); next.post(nif);
controller.post(nif); controller.post(nif);
@ -78,7 +78,7 @@ namespace Nif
data.read(nif); data.read(nif);
} }
void NiParticleColorModifier::post(NIFFile* nif) void NiParticleColorModifier::post(Reader& nif)
{ {
NiParticleModifier::post(nif); NiParticleModifier::post(nif);
data.post(nif); data.post(nif);

View file

@ -62,7 +62,7 @@ namespace Nif
unsigned int alpha; unsigned int alpha;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct BSShaderTextureSet : public Record struct BSShaderTextureSet : public Record
@ -89,7 +89,7 @@ namespace Nif
ControllerPtr controller; ControllerPtr controller;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiParticleGrowFade : public NiParticleModifier struct NiParticleGrowFade : public NiParticleModifier
@ -105,7 +105,7 @@ namespace Nif
NiColorDataPtr data; NiColorDataPtr data;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiGravity : public NiParticleModifier struct NiGravity : public NiParticleModifier

View file

@ -22,7 +22,7 @@ namespace Nif
target.read(nif); target.read(nif);
} }
void Controller::post(NIFFile* nif) void Controller::post(Reader& nif)
{ {
Record::post(nif); Record::post(nif);
next.post(nif); next.post(nif);
@ -44,7 +44,7 @@ namespace Nif
mInterpolator.read(nif); mInterpolator.read(nif);
} }
void NiSingleInterpController::post(NIFFile* nif) void NiSingleInterpController::post(Reader& nif)
{ {
NiInterpController::post(nif); NiInterpController::post(nif);
mInterpolator.post(nif); mInterpolator.post(nif);
@ -104,7 +104,7 @@ namespace Nif
nif->getChar(); nif->getChar();
} }
void NiParticleSystemController::post(NIFFile* nif) void NiParticleSystemController::post(Reader& nif)
{ {
Controller::post(nif); Controller::post(nif);
emitter.post(nif); emitter.post(nif);
@ -128,7 +128,7 @@ namespace Nif
mData.read(nif); mData.read(nif);
} }
void NiMaterialColorController::post(NIFFile* nif) void NiMaterialColorController::post(Reader& nif)
{ {
NiPoint3InterpController::post(nif); NiPoint3InterpController::post(nif);
mData.post(nif); mData.post(nif);
@ -142,7 +142,7 @@ namespace Nif
target.read(nif); target.read(nif);
} }
void NiLookAtController::post(NIFFile* nif) void NiLookAtController::post(Reader& nif)
{ {
Controller::post(nif); Controller::post(nif);
target.post(nif); target.post(nif);
@ -160,7 +160,7 @@ namespace Nif
floatData.read(nif); floatData.read(nif);
} }
void NiPathController::post(NIFFile* nif) void NiPathController::post(Reader& nif)
{ {
Controller::post(nif); Controller::post(nif);
@ -176,7 +176,7 @@ namespace Nif
data.read(nif); data.read(nif);
} }
void NiUVController::post(NIFFile* nif) void NiUVController::post(Reader& nif)
{ {
Controller::post(nif); Controller::post(nif);
data.post(nif); data.post(nif);
@ -189,7 +189,7 @@ namespace Nif
mData.read(nif); mData.read(nif);
} }
void NiKeyframeController::post(NIFFile* nif) void NiKeyframeController::post(Reader& nif)
{ {
NiSingleInterpController::post(nif); NiSingleInterpController::post(nif);
mData.post(nif); mData.post(nif);
@ -206,7 +206,7 @@ namespace Nif
mExtraTargets = targets; mExtraTargets = targets;
} }
void NiMultiTargetTransformController::post(NIFFile* nif) void NiMultiTargetTransformController::post(Reader& nif)
{ {
NiInterpController::post(nif); NiInterpController::post(nif);
mExtraTargets.post(nif); mExtraTargets.post(nif);
@ -219,7 +219,7 @@ namespace Nif
mData.read(nif); mData.read(nif);
} }
void NiAlphaController::post(NIFFile* nif) void NiAlphaController::post(Reader& nif)
{ {
NiFloatInterpController::post(nif); NiFloatInterpController::post(nif);
mData.post(nif); mData.post(nif);
@ -232,7 +232,7 @@ namespace Nif
mData.read(nif); mData.read(nif);
} }
void NiRollController::post(NIFFile* nif) void NiRollController::post(Reader& nif)
{ {
NiSingleInterpController::post(nif); NiSingleInterpController::post(nif);
mData.post(nif); mData.post(nif);
@ -275,7 +275,7 @@ namespace Nif
} }
} }
void NiGeomMorpherController::post(NIFFile* nif) void NiGeomMorpherController::post(Reader& nif)
{ {
NiInterpController::post(nif); NiInterpController::post(nif);
mData.post(nif); mData.post(nif);
@ -289,7 +289,7 @@ namespace Nif
mData.read(nif); mData.read(nif);
} }
void NiVisController::post(NIFFile* nif) void NiVisController::post(Reader& nif)
{ {
NiBoolInterpController::post(nif); NiBoolInterpController::post(nif);
mData.post(nif); mData.post(nif);
@ -307,7 +307,7 @@ namespace Nif
mSources.read(nif); mSources.read(nif);
} }
void NiFlipController::post(NIFFile* nif) void NiFlipController::post(Reader& nif)
{ {
NiFloatInterpController::post(nif); NiFloatInterpController::post(nif);
mSources.post(nif); mSources.post(nif);
@ -334,7 +334,7 @@ namespace Nif
data.read(nif); data.read(nif);
} }
void NiPoint3Interpolator::post(NIFFile* nif) void NiPoint3Interpolator::post(Reader& nif)
{ {
data.post(nif); data.post(nif);
} }
@ -345,7 +345,7 @@ namespace Nif
data.read(nif); data.read(nif);
} }
void NiBoolInterpolator::post(NIFFile* nif) void NiBoolInterpolator::post(Reader& nif)
{ {
data.post(nif); data.post(nif);
} }
@ -356,7 +356,7 @@ namespace Nif
data.read(nif); data.read(nif);
} }
void NiFloatInterpolator::post(NIFFile* nif) void NiFloatInterpolator::post(Reader& nif)
{ {
data.post(nif); data.post(nif);
} }
@ -378,7 +378,7 @@ namespace Nif
data.read(nif); data.read(nif);
} }
void NiTransformInterpolator::post(NIFFile* nif) void NiTransformInterpolator::post(Reader& nif)
{ {
data.post(nif); data.post(nif);
} }
@ -389,7 +389,7 @@ namespace Nif
data.read(nif); data.read(nif);
} }
void NiColorInterpolator::post(NIFFile* nif) void NiColorInterpolator::post(Reader& nif)
{ {
data.post(nif); data.post(nif);
} }

View file

@ -44,7 +44,7 @@ namespace Nif
NiInterpolatorPtr mInterpolator; NiInterpolatorPtr mInterpolator;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
// Base class for controllers that use a NiFloatInterpolator to animate their target. // Base class for controllers that use a NiFloatInterpolator to animate their target.
@ -116,7 +116,7 @@ namespace Nif
NiParticleModifierPtr colliders; NiParticleModifierPtr colliders;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
bool noAutoAdjust() const { return emitFlags & EmitFlag_NoAutoAdjust; } bool noAutoAdjust() const { return emitFlags & EmitFlag_NoAutoAdjust; }
bool emitAtVertex() const { return flags & BSPArrayController_AtVertex; } bool emitAtVertex() const { return flags & BSPArrayController_AtVertex; }
@ -129,7 +129,7 @@ namespace Nif
unsigned int mTargetColor; unsigned int mTargetColor;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiPathController : public Controller struct NiPathController : public Controller
@ -152,7 +152,7 @@ namespace Nif
short followAxis; short followAxis;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiLookAtController : public Controller struct NiLookAtController : public Controller
@ -161,7 +161,7 @@ namespace Nif
unsigned short lookAtFlags{ 0 }; unsigned short lookAtFlags{ 0 };
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiUVController : public Controller struct NiUVController : public Controller
@ -170,7 +170,7 @@ namespace Nif
unsigned int uvSet; unsigned int uvSet;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiKeyframeController : public NiSingleInterpController struct NiKeyframeController : public NiSingleInterpController
@ -178,7 +178,7 @@ namespace Nif
NiKeyframeDataPtr mData; NiKeyframeDataPtr mData;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiMultiTargetTransformController : public NiInterpController struct NiMultiTargetTransformController : public NiInterpController
@ -186,7 +186,7 @@ namespace Nif
NodeList mExtraTargets; NodeList mExtraTargets;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiAlphaController : public NiFloatInterpController struct NiAlphaController : public NiFloatInterpController
@ -194,7 +194,7 @@ namespace Nif
NiFloatDataPtr mData; NiFloatDataPtr mData;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiRollController : public NiSingleInterpController struct NiRollController : public NiSingleInterpController
@ -202,7 +202,7 @@ namespace Nif
NiFloatDataPtr mData; NiFloatDataPtr mData;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiGeomMorpherController : public NiInterpController struct NiGeomMorpherController : public NiInterpController
@ -214,7 +214,7 @@ namespace Nif
std::vector<float> mWeights; std::vector<float> mWeights;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiVisController : public NiBoolInterpController struct NiVisController : public NiBoolInterpController
@ -222,7 +222,7 @@ namespace Nif
NiVisDataPtr mData; NiVisDataPtr mData;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiFlipController : public NiFloatInterpController struct NiFlipController : public NiFloatInterpController
@ -232,7 +232,7 @@ namespace Nif
NiSourceTextureList mSources; NiSourceTextureList mSources;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct bhkBlendController : public Controller struct bhkBlendController : public Controller
@ -255,7 +255,7 @@ namespace Nif
osg::Vec3f defaultVal; osg::Vec3f defaultVal;
NiPosDataPtr data; NiPosDataPtr data;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiBoolInterpolator : public NiInterpolator struct NiBoolInterpolator : public NiInterpolator
@ -263,7 +263,7 @@ namespace Nif
char defaultVal; char defaultVal;
NiBoolDataPtr data; NiBoolDataPtr data;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiFloatInterpolator : public NiInterpolator struct NiFloatInterpolator : public NiInterpolator
@ -271,7 +271,7 @@ namespace Nif
float defaultVal; float defaultVal;
NiFloatDataPtr data; NiFloatDataPtr data;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiTransformInterpolator : public NiInterpolator struct NiTransformInterpolator : public NiInterpolator
@ -282,7 +282,7 @@ namespace Nif
NiKeyframeDataPtr data; NiKeyframeDataPtr data;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiColorInterpolator : public NiInterpolator struct NiColorInterpolator : public NiInterpolator
@ -290,7 +290,7 @@ namespace Nif
osg::Vec4f defaultVal; osg::Vec4f defaultVal;
NiColorDataPtr data; NiColorDataPtr data;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
} // Namespace } // Namespace

View file

@ -16,7 +16,7 @@ namespace Nif
bones.read(nif); bones.read(nif);
} }
void NiSkinInstance::post(NIFFile* nif) void NiSkinInstance::post(Reader& nif)
{ {
data.post(nif); data.post(nif);
partitions.post(nif); partitions.post(nif);
@ -24,16 +24,16 @@ namespace Nif
bones.post(nif); bones.post(nif);
if (data.empty() || root.empty()) if (data.empty() || root.empty())
throw Nif::Exception("NiSkinInstance missing root or data", nif->getFilename()); throw Nif::Exception("NiSkinInstance missing root or data", nif.getFilename());
size_t bnum = bones.length(); size_t bnum = bones.length();
if (bnum != data->bones.size()) if (bnum != data->bones.size())
throw Nif::Exception("Mismatch in NiSkinData bone count", nif->getFilename()); throw Nif::Exception("Mismatch in NiSkinData bone count", nif.getFilename());
for (size_t i = 0; i < bnum; i++) for (size_t i = 0; i < bnum; i++)
{ {
if (bones[i].empty()) if (bones[i].empty())
throw Nif::Exception("Oops: Missing bone! Don't know how to handle this.", nif->getFilename()); throw Nif::Exception("Oops: Missing bone! Don't know how to handle this.", nif.getFilename());
bones[i]->setBone(); bones[i]->setBone();
} }
} }
@ -304,7 +304,7 @@ namespace Nif
nif->getUChars(data, numPixels * numFaces); nif->getUChars(data, numPixels * numFaces);
} }
void NiPixelData::post(NIFFile* nif) void NiPixelData::post(Reader& nif)
{ {
palette.post(nif); palette.post(nif);
} }
@ -360,7 +360,7 @@ namespace Nif
} }
} }
void NiSkinData::post(NIFFile* nif) void NiSkinData::post(Reader& nif)
{ {
partitions.post(nif); partitions.post(nif);
} }
@ -474,7 +474,7 @@ namespace Nif
palette = nif->getString(); palette = nif->getString();
if (nif->getUInt() != palette.size()) if (nif->getUInt() != palette.size())
Log(Debug::Warning) << "NIFFile Warning: Failed size check in NiStringPalette. File: " Log(Debug::Warning) << "NIFFile Warning: Failed size check in NiStringPalette. File: "
<< nif->file->getFilename(); << nif->getFile().getFilename();
} }
void NiBoolData::read(NIFStream* nif) void NiBoolData::read(NIFStream* nif)

View file

@ -139,7 +139,7 @@ namespace Nif
std::vector<unsigned char> data; std::vector<unsigned char> data;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiColorData : public Record struct NiColorData : public Record
@ -169,7 +169,7 @@ namespace Nif
NodeList bones; NodeList bones;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct BSDismemberSkinInstance : public NiSkinInstance struct BSDismemberSkinInstance : public NiSkinInstance
@ -198,7 +198,7 @@ namespace Nif
NiSkinPartitionPtr partitions; NiSkinPartitionPtr partitions;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiSkinPartition : public Record struct NiSkinPartition : public Record

View file

@ -60,7 +60,7 @@ namespace Nif
nif->skip(2); // Unknown short nif->skip(2); // Unknown short
} }
void NiTextureEffect::post(NIFFile* nif) void NiTextureEffect::post(Reader& nif)
{ {
NiDynamicEffect::post(nif); NiDynamicEffect::post(nif);
texture.post(nif); texture.post(nif);

View file

@ -86,7 +86,7 @@ namespace Nif
CoordGenType coordGenType; CoordGenType coordGenType;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
bool wrapT() const { return clamp & 1; } bool wrapT() const { return clamp & 1; }
bool wrapS() const { return (clamp >> 1) & 1; } bool wrapS() const { return (clamp >> 1) & 1; }

View file

@ -23,11 +23,16 @@
namespace Nif namespace Nif
{ {
/// Open a NIF stream. The name is used for error messages. Reader::Reader(NIFFile& file)
NIFFile::NIFFile(Files::IStreamPtr&& stream, const std::filesystem::path& name) : ver(file.mVersion)
: filename(name) , userVer(file.mUserVersion)
, bethVer(file.mBethVersion)
, filename(file.mPath)
, hash(file.mHash)
, records(file.mRecords)
, roots(file.mRoots)
, mUseSkinning(file.mUseSkinning)
{ {
parse(std::move(stream));
} }
template <typename NodeType, RecordType recordType> template <typename NodeType, RecordType recordType>
@ -173,7 +178,7 @@ namespace Nif
/// Make the factory map used for parsing the file /// Make the factory map used for parsing the file
static const std::map<std::string, CreateRecord> factories = makeFactory(); static const std::map<std::string, CreateRecord> factories = makeFactory();
std::string NIFFile::printVersion(unsigned int version) std::string Reader::printVersion(unsigned int version)
{ {
int major = (version >> 24) & 0xFF; int major = (version >> 24) & 0xFF;
int minor = (version >> 16) & 0xFF; int minor = (version >> 16) & 0xFF;
@ -185,12 +190,12 @@ namespace Nif
return stream.str(); return stream.str();
} }
void NIFFile::parse(Files::IStreamPtr&& stream) void Reader::parse(Files::IStreamPtr&& stream)
{ {
const std::array<std::uint64_t, 2> fileHash = Files::getHash(filename, *stream); const std::array<std::uint64_t, 2> fileHash = Files::getHash(filename, *stream);
hash.append(reinterpret_cast<const char*>(fileHash.data()), fileHash.size() * sizeof(std::uint64_t)); hash.append(reinterpret_cast<const char*>(fileHash.data()), fileHash.size() * sizeof(std::uint64_t));
NIFStream nif(this, std::move(stream)); NIFStream nif(*this, std::move(stream));
// Check the header string // Check the header string
std::string head = nif.getVersionString(); std::string head = nif.getVersionString();
@ -209,7 +214,7 @@ namespace Nif
// It's not used by Morrowind assets but Morrowind supports it. // It's not used by Morrowind assets but Morrowind supports it.
static const std::array<uint32_t, 2> supportedVers = { static const std::array<uint32_t, 2> supportedVers = {
NIFStream::generateVersion(4, 0, 0, 0), NIFStream::generateVersion(4, 0, 0, 0),
VER_MW, NIFFile::VER_MW,
}; };
const bool supportedVersion = std::find(supportedVers.begin(), supportedVers.end(), ver) != supportedVers.end(); const bool supportedVersion = std::find(supportedVers.begin(), supportedVers.end(), ver) != supportedVers.end();
if (!supportedVersion) if (!supportedVersion)
@ -239,19 +244,19 @@ namespace Nif
// Bethesda stream header // Bethesda stream header
// It contains Bethesda format version and (useless) export information // It contains Bethesda format version and (useless) export information
if (ver == VER_OB_OLD if (ver == NIFFile::VER_OB_OLD
|| (userVer >= 3 || (userVer >= 3
&& ((ver == VER_OB || ver == VER_BGS) && ((ver == NIFFile::VER_OB || ver == NIFFile::VER_BGS)
|| (ver >= NIFStream::generateVersion(10, 1, 0, 0) && ver <= NIFStream::generateVersion(20, 0, 0, 4) || (ver >= NIFStream::generateVersion(10, 1, 0, 0) && ver <= NIFStream::generateVersion(20, 0, 0, 4)
&& userVer <= 11)))) && userVer <= 11))))
{ {
bethVer = nif.getUInt(); bethVer = nif.getUInt();
nif.getExportString(); // Author nif.getExportString(); // Author
if (bethVer > BETHVER_FO4) if (bethVer > NIFFile::BETHVER_FO4)
nif.getUInt(); // Unknown nif.getUInt(); // Unknown
nif.getExportString(); // Process script nif.getExportString(); // Process script
nif.getExportString(); // Export script nif.getExportString(); // Export script
if (bethVer == BETHVER_FO4) if (bethVer == NIFFile::BETHVER_FO4)
nif.getExportString(); // Max file path nif.getExportString(); // Max file path
} }
@ -347,29 +352,24 @@ namespace Nif
// Once parsing is done, do post-processing. // Once parsing is done, do post-processing.
for (const auto& record : records) for (const auto& record : records)
record->post(this); record->post(*this);
} }
void NIFFile::setUseSkinning(bool skinning) void Reader::setUseSkinning(bool skinning)
{ {
mUseSkinning = skinning; mUseSkinning = skinning;
} }
bool NIFFile::getUseSkinning() const std::atomic_bool Reader::sLoadUnsupportedFiles = false;
{
return mUseSkinning;
}
std::atomic_bool NIFFile::sLoadUnsupportedFiles = false; void Reader::setLoadUnsupportedFiles(bool load)
void NIFFile::setLoadUnsupportedFiles(bool load)
{ {
sLoadUnsupportedFiles = load; sLoadUnsupportedFiles = load;
} }
std::string NIFFile::getString(uint32_t index) const std::string Reader::getString(std::uint32_t index) const
{ {
if (index == std::numeric_limits<uint32_t>::max()) if (index == std::numeric_limits<std::uint32_t>::max())
return std::string(); return std::string();
return strings.at(index); return strings.at(index);
} }

View file

@ -14,72 +14,8 @@
namespace Nif namespace Nif
{ {
struct File struct NIFFile
{ {
virtual ~File() = default;
virtual Record* getRecord(size_t index) const = 0;
virtual size_t numRecords() const = 0;
virtual Record* getRoot(size_t index = 0) const = 0;
virtual size_t numRoots() const = 0;
virtual std::string getString(uint32_t index) const = 0;
virtual void setUseSkinning(bool skinning) = 0;
virtual bool getUseSkinning() const = 0;
virtual std::filesystem::path getFilename() const = 0;
virtual std::string getHash() const = 0;
virtual unsigned int getVersion() const = 0;
virtual unsigned int getUserVersion() const = 0;
virtual unsigned int getBethVersion() const = 0;
};
class NIFFile final : public File
{
/// File version, user version, Bethesda version
unsigned int ver = 0;
unsigned int userVer = 0;
unsigned int bethVer = 0;
/// File name, used for error messages and opening the file
std::filesystem::path filename;
std::string hash;
/// Record list
std::vector<std::unique_ptr<Record>> records;
/// Root list. This is a select portion of the pointers from records
std::vector<Record*> roots;
/// String table
std::vector<std::string> strings;
bool mUseSkinning = false;
static std::atomic_bool sLoadUnsupportedFiles;
/// Parse the file
void parse(Files::IStreamPtr&& stream);
/// Get the file's version in a human readable form
///\returns A string containing a human readable NIF version number
std::string printVersion(unsigned int version);
/// Private Copy Constructor
NIFFile(NIFFile const&);
///\overload
void operator=(NIFFile const&);
public:
// For generic versions NIFStream::generateVersion() is used instead // For generic versions NIFStream::generateVersion() is used instead
enum NIFVersion enum NIFVersion
{ {
@ -94,45 +30,107 @@ namespace Nif
BETHVER_FO4 = 130 // Fallout 4 BETHVER_FO4 = 130 // Fallout 4
}; };
/// Open a NIF stream. The name is used for error messages. /// File version, user version, Bethesda version
NIFFile(Files::IStreamPtr&& stream, const std::filesystem::path& name); unsigned int mVersion = 0;
unsigned int mUserVersion = 0;
unsigned int mBethVersion = 0;
/// Get a given record /// File name, used for error messages and opening the file
Record* getRecord(size_t index) const override { return records.at(index).get(); } std::filesystem::path mPath;
/// Number of records std::string mHash;
size_t numRecords() const override { return records.size(); }
/// Record list
std::vector<std::unique_ptr<Record>> mRecords;
/// Root list. This is a select portion of the pointers from records
std::vector<Record*> mRoots;
bool mUseSkinning = false;
explicit NIFFile(const std::filesystem::path& path)
: mPath(path)
{
}
/// Get a given root /// Get a given root
Record* getRoot(size_t index = 0) const override Record* getRoot(size_t index = 0) const { return mRoots.at(index); }
{
Record* res = roots.at(index);
return res;
}
/// Number of roots /// Number of roots
size_t numRoots() const override { return roots.size(); } std::size_t numRoots() const { return mRoots.size(); }
/// Get the name of the file
const std::filesystem::path& getFilename() const { return mPath; }
const std::string& getHash() const { return mHash; }
/// Get the version of the NIF format used
unsigned int getVersion() const { return mVersion; }
/// Get the user version of the NIF format used
unsigned int getUserVersion() const { return mUserVersion; }
/// Get the Bethesda version of the NIF format used
unsigned int getBethVersion() const { return mBethVersion; }
bool getUseSkinning() const { return mUseSkinning; }
};
class Reader
{
/// File version, user version, Bethesda version
unsigned int& ver;
unsigned int& userVer;
unsigned int& bethVer;
/// File name, used for error messages and opening the file
std::filesystem::path& filename;
std::string& hash;
/// Record list
std::vector<std::unique_ptr<Record>>& records;
/// Root list. This is a select portion of the pointers from records
std::vector<Record*>& roots;
/// String table
std::vector<std::string> strings;
bool& mUseSkinning;
static std::atomic_bool sLoadUnsupportedFiles;
/// Get the file's version in a human readable form
///\returns A string containing a human readable NIF version number
std::string printVersion(unsigned int version);
public:
/// Open a NIF stream. The name is used for error messages.
explicit Reader(NIFFile& file);
/// Parse the file
void parse(Files::IStreamPtr&& stream);
/// Get a given record
Record* getRecord(size_t index) const { return records.at(index).get(); }
/// Get a given string from the file's string table /// Get a given string from the file's string table
std::string getString(uint32_t index) const override; std::string getString(uint32_t index) const;
/// Set whether there is skinning contained in this NIF file. /// Set whether there is skinning contained in this NIF file.
/// @note This is just a hint for users of the NIF file and has no effect on the loading procedure. /// @note This is just a hint for users of the NIF file and has no effect on the loading procedure.
void setUseSkinning(bool skinning) override; void setUseSkinning(bool skinning);
bool getUseSkinning() const override;
/// Get the name of the file /// Get the name of the file
std::filesystem::path getFilename() const override { return filename; } std::filesystem::path getFilename() const { return filename; }
std::string getHash() const override { return hash; }
/// Get the version of the NIF format used /// Get the version of the NIF format used
unsigned int getVersion() const override { return ver; } unsigned int getVersion() const { return ver; }
/// Get the user version of the NIF format used /// Get the user version of the NIF format used
unsigned int getUserVersion() const override { return userVer; } unsigned int getUserVersion() const { return userVer; }
/// Get the Bethesda version of the NIF format used /// Get the Bethesda version of the NIF format used
unsigned int getBethVersion() const override { return bethVer; } unsigned int getBethVersion() const { return bethVer; }
static void setLoadUnsupportedFiles(bool load); static void setLoadUnsupportedFiles(bool load);
}; };

View file

@ -113,8 +113,8 @@ namespace Nif
} }
else if (count != 0) else if (count != 0)
{ {
throw Nif::Exception( throw Nif::Exception("Unhandled interpolation type: " + std::to_string(mInterpolationType),
"Unhandled interpolation type: " + std::to_string(mInterpolationType), nif->file->getFilename()); nif->getFile().getFilename());
} }
} }

View file

@ -34,20 +34,20 @@ namespace Nif
/// Read in a string, either from the string table using the index or from the stream using the specified length /// Read in a string, either from the string table using the index or from the stream using the specified length
std::string NIFStream::getString() std::string NIFStream::getString()
{ {
return getVersion() < generateVersion(20, 1, 0, 1) ? getSizedString() : file->getString(getUInt()); return getVersion() < generateVersion(20, 1, 0, 1) ? getSizedString() : file.getString(getUInt());
} }
// Convenience utility functions: get the versions of the currently read file // Convenience utility functions: get the versions of the currently read file
unsigned int NIFStream::getVersion() const unsigned int NIFStream::getVersion() const
{ {
return file->getVersion(); return file.getVersion();
} }
unsigned int NIFStream::getUserVersion() const unsigned int NIFStream::getUserVersion() const
{ {
return file->getBethVersion(); return file.getBethVersion();
} }
unsigned int NIFStream::getBethVersion() const unsigned int NIFStream::getBethVersion() const
{ {
return file->getBethVersion(); return file.getBethVersion();
} }
} }

View file

@ -22,7 +22,7 @@
namespace Nif namespace Nif
{ {
class NIFFile; class Reader;
template <std::size_t numInstances, typename T> template <std::size_t numInstances, typename T>
inline void readLittleEndianBufferOfType(Files::IStreamPtr& pIStream, T* dest) inline void readLittleEndianBufferOfType(Files::IStreamPtr& pIStream, T* dest)
@ -59,18 +59,20 @@ namespace Nif
class NIFStream class NIFStream
{ {
const Reader& file;
/// Input stream /// Input stream
Files::IStreamPtr inp; Files::IStreamPtr inp;
public: public:
NIFFile* const file; explicit NIFStream(const Reader& file, Files::IStreamPtr&& inp)
: file(file)
NIFStream(NIFFile* file, Files::IStreamPtr&& inp) , inp(std::move(inp))
: inp(std::move(inp))
, file(file)
{ {
} }
const Reader& getFile() const { return file; }
void skip(size_t size) { inp->ignore(size); } void skip(size_t size) { inp->ignore(size); }
char getChar() { return readLittleEndianType<char>(inp); } char getChar() { return readLittleEndianType<char>(inp); }

View file

@ -70,7 +70,7 @@ namespace Nif
default: default:
{ {
throw Nif::Exception( throw Nif::Exception(
"Unhandled NiBoundingVolume type: " + std::to_string(type), nif->file->getFilename()); "Unhandled NiBoundingVolume type: " + std::to_string(type), nif->getFile().getFilename());
} }
} }
} }
@ -99,7 +99,7 @@ namespace Nif
isBone = false; isBone = false;
} }
void Node::post(NIFFile* nif) void Node::post(Reader& nif)
{ {
Named::post(nif); Named::post(nif);
props.post(nif); props.post(nif);
@ -128,7 +128,7 @@ namespace Nif
} }
} }
void NiNode::post(NIFFile* nif) void NiNode::post(Reader& nif)
{ {
Node::post(nif); Node::post(nif);
children.post(nif); children.post(nif);
@ -176,7 +176,7 @@ namespace Nif
} }
} }
void NiGeometry::post(NIFFile* nif) void NiGeometry::post(Reader& nif)
{ {
Node::post(nif); Node::post(nif);
data.post(nif); data.post(nif);
@ -184,7 +184,7 @@ namespace Nif
shaderprop.post(nif); shaderprop.post(nif);
alphaprop.post(nif); alphaprop.post(nif);
if (recType != RC_NiParticles && !skin.empty()) if (recType != RC_NiParticles && !skin.empty())
nif->setUseSkinning(true); nif.setUseSkinning(true);
} }
void BSLODTriShape::read(NIFStream* nif) void BSLODTriShape::read(NIFStream* nif)
@ -271,7 +271,7 @@ namespace Nif
mSubSorter.read(nif); mSubSorter.read(nif);
} }
void NiSortAdjustNode::post(NIFFile* nif) void NiSortAdjustNode::post(Reader& nif)
{ {
NiNode::post(nif); NiNode::post(nif);
mSubSorter.post(nif); mSubSorter.post(nif);

View file

@ -94,7 +94,7 @@ namespace Nif
NiCollisionObjectPtr collision; NiCollisionObjectPtr collision;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
// Parent node, or nullptr for the root node. As far as I'm aware, only // Parent node, or nullptr for the root node. As far as I'm aware, only
// NiNodes (or types derived from NiNodes) can be parents. // NiNodes (or types derived from NiNodes) can be parents.
@ -126,7 +126,7 @@ namespace Nif
}; };
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiGeometry : Node struct NiGeometry : Node
@ -154,7 +154,7 @@ namespace Nif
NiAlphaPropertyPtr alphaprop; NiAlphaPropertyPtr alphaprop;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiTriShape : NiGeometry struct NiTriShape : NiGeometry
@ -263,7 +263,7 @@ namespace Nif
NiAccumulatorPtr mSubSorter; NiAccumulatorPtr mSubSorter;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiBillboardNode : NiNode struct NiBillboardNode : NiNode

View file

@ -165,7 +165,7 @@ namespace Nif
mWorldObjectInfo.read(nif); mWorldObjectInfo.read(nif);
} }
void bhkWorldObject::post(NIFFile* nif) void bhkWorldObject::post(Reader& nif)
{ {
mShape.post(nif); mShape.post(nif);
} }
@ -181,7 +181,7 @@ namespace Nif
mShape.read(nif); mShape.read(nif);
} }
void bhkBvTreeShape::post(NIFFile* nif) void bhkBvTreeShape::post(Reader& nif)
{ {
mShape.post(nif); mShape.post(nif);
} }
@ -207,7 +207,7 @@ namespace Nif
nif->getUInts(mFilters, numFilters); nif->getUInts(mFilters, numFilters);
} }
void bhkNiTriStripsShape::post(NIFFile* nif) void bhkNiTriStripsShape::post(Reader& nif)
{ {
mData.post(nif); mData.post(nif);
} }
@ -229,7 +229,7 @@ namespace Nif
mData.read(nif); mData.read(nif);
} }
void bhkPackedNiTriStripsShape::post(NIFFile* nif) void bhkPackedNiTriStripsShape::post(Reader& nif)
{ {
mData.post(nif); mData.post(nif);
} }

View file

@ -17,7 +17,7 @@ namespace Nif
{ {
class NIFStream; class NIFStream;
class NIFFile; struct NIFFile;
/// Non-record data types /// Non-record data types
@ -204,7 +204,7 @@ namespace Nif
NodePtr mTarget; NodePtr mTarget;
void read(NIFStream* nif) override { mTarget.read(nif); } void read(NIFStream* nif) override { mTarget.read(nif); }
void post(NIFFile* nif) override { mTarget.post(nif); } void post(Reader& nif) override { mTarget.post(nif); }
}; };
// Bethesda Havok-specific collision object // Bethesda Havok-specific collision object
@ -214,7 +214,7 @@ namespace Nif
bhkWorldObjectPtr mBody; bhkWorldObjectPtr mBody;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override void post(Reader& nif) override
{ {
NiCollisionObject::post(nif); NiCollisionObject::post(nif);
mBody.post(nif); mBody.post(nif);
@ -228,7 +228,7 @@ namespace Nif
HavokFilter mHavokFilter; HavokFilter mHavokFilter;
bhkWorldObjectCInfo mWorldObjectInfo; bhkWorldObjectCInfo mWorldObjectInfo;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
// Abstract // Abstract
@ -244,7 +244,7 @@ namespace Nif
{ {
bhkShapePtr mShape; bhkShapePtr mShape;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
// bhkBvTreeShape with Havok MOPP code // bhkBvTreeShape with Havok MOPP code
@ -265,7 +265,7 @@ namespace Nif
NiTriStripsDataList mData; NiTriStripsDataList mData;
std::vector<unsigned int> mFilters; std::vector<unsigned int> mFilters;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
// Bethesda packed triangle strip-based Havok shape collection // Bethesda packed triangle strip-based Havok shape collection
@ -278,7 +278,7 @@ namespace Nif
hkPackedNiTriStripsDataPtr mData; hkPackedNiTriStripsDataPtr mData;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
// bhkPackedNiTriStripsShape data block // bhkPackedNiTriStripsShape data block

View file

@ -47,7 +47,7 @@ namespace Nif
} }
} }
void NiTexturingProperty::Texture::post(NIFFile* nif) void NiTexturingProperty::Texture::post(Reader& nif)
{ {
texture.post(nif); texture.post(nif);
} }
@ -92,7 +92,7 @@ namespace Nif
} }
} }
void NiTexturingProperty::post(NIFFile* nif) void NiTexturingProperty::post(Reader& nif)
{ {
Property::post(nif); Property::post(nif);
for (size_t i = 0; i < textures.size(); i++) for (size_t i = 0; i < textures.size(); i++)
@ -134,7 +134,7 @@ namespace Nif
parallax.scale = nif->getFloat(); parallax.scale = nif->getFloat();
} }
void BSShaderPPLightingProperty::post(NIFFile* nif) void BSShaderPPLightingProperty::post(Reader& nif)
{ {
BSShaderLightingProperty::post(nif); BSShaderLightingProperty::post(nif);
textureSet.post(nif); textureSet.post(nif);
@ -198,7 +198,7 @@ namespace Nif
} }
} }
void BSLightingShaderProperty::post(NIFFile* nif) void BSLightingShaderProperty::post(Reader& nif)
{ {
BSShaderProperty::post(nif); BSShaderProperty::post(nif);
mTextureSet.post(nif); mTextureSet.post(nif);

View file

@ -53,7 +53,7 @@ namespace Nif
unsigned int clamp, uvSet; unsigned int clamp, uvSet;
void read(NIFStream* nif); void read(NIFStream* nif);
void post(NIFFile* nif); void post(Reader& nif);
bool wrapT() const { return clamp & 1; } bool wrapT() const { return clamp & 1; }
bool wrapS() const { return (clamp >> 1) & 1; } bool wrapS() const { return (clamp >> 1) & 1; }
@ -97,7 +97,7 @@ namespace Nif
osg::Vec4f bumpMapMatrix; osg::Vec4f bumpMapMatrix;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiFogProperty : public Property struct NiFogProperty : public Property
@ -166,7 +166,7 @@ namespace Nif
ParallaxSettings parallax; ParallaxSettings parallax;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct BSShaderNoLightingProperty : public BSShaderLightingProperty struct BSShaderNoLightingProperty : public BSShaderLightingProperty
@ -212,7 +212,7 @@ namespace Nif
float mEmissiveMult, mSpecStrength; float mEmissiveMult, mSpecStrength;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(NIFFile* nif) override; void post(Reader& nif) override;
}; };
struct NiDitherProperty : public Property struct NiDitherProperty : public Property

View file

@ -29,7 +29,7 @@
namespace Nif namespace Nif
{ {
class NIFFile; class Reader;
class NIFStream; class NIFStream;
enum RecordType enum RecordType
@ -164,7 +164,7 @@ namespace Nif
virtual void read(NIFStream* nif) = 0; virtual void read(NIFStream* nif) = 0;
/// Does post-processing, after the entire tree is loaded /// Does post-processing, after the entire tree is loaded
virtual void post(NIFFile* nif) {} virtual void post(Reader& nif) {}
virtual ~Record() {} virtual ~Record() {}
}; };

View file

@ -44,13 +44,13 @@ namespace Nif
} }
/// Resolve index to pointer /// Resolve index to pointer
void post(NIFFile* nif) void post(Reader& nif)
{ {
if (index < 0) if (index < 0)
ptr = nullptr; ptr = nullptr;
else else
{ {
Record* r = nif->getRecord(index); Record* r = nif.getRecord(index);
// And cast it // And cast it
ptr = dynamic_cast<X*>(r); ptr = dynamic_cast<X*>(r);
assert(ptr != nullptr); assert(ptr != nullptr);
@ -107,7 +107,7 @@ namespace Nif
list[i].read(nif); list[i].read(nif);
} }
void post(NIFFile* nif) void post(Reader& nif)
{ {
for (size_t i = 0; i < list.size(); i++) for (size_t i = 0; i < list.size(); i++)
list[i].post(nif); list[i].post(nif);

View file

@ -160,7 +160,7 @@ namespace
namespace NifBullet namespace NifBullet
{ {
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif) osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::NIFFile& nif)
{ {
mShape = new Resource::BulletShape; mShape = new Resource::BulletShape;

View file

@ -48,7 +48,7 @@ namespace NifBullet
abort(); abort();
} }
osg::ref_ptr<Resource::BulletShape> load(const Nif::File& file); osg::ref_ptr<Resource::BulletShape> load(const Nif::NIFFile& file);
private: private:
bool findBoundingBox(const Nif::Node& node, const std::string& filename); bool findBoundingBox(const Nif::Node& node, const std::string& filename);

View file

@ -963,7 +963,7 @@ namespace NifOsg
if (matctrl->mData.empty() && matctrl->mInterpolator.empty()) if (matctrl->mData.empty() && matctrl->mInterpolator.empty())
continue; continue;
auto targetColor = static_cast<MaterialColorController::TargetColor>(matctrl->mTargetColor); auto targetColor = static_cast<MaterialColorController::TargetColor>(matctrl->mTargetColor);
if (mVersion <= Nif::NIFFile::NIFVersion::VER_MW if (mVersion <= Nif::NIFFile::VER_MW
&& targetColor == MaterialColorController::TargetColor::Specular) && targetColor == MaterialColorController::TargetColor::Specular)
continue; continue;
if (!matctrl->mInterpolator.empty() if (!matctrl->mInterpolator.empty()
@ -2398,7 +2398,7 @@ namespace NifOsg
} }
// While NetImmerse and Gamebryo support specular lighting, Morrowind has its support disabled. // While NetImmerse and Gamebryo support specular lighting, Morrowind has its support disabled.
if (mVersion <= Nif::NIFFile::NIFVersion::VER_MW || !specEnabled) if (mVersion <= Nif::NIFFile::VER_MW || !specEnabled)
mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f));
if (lightmode == 0) if (lightmode == 0)

View file

@ -156,8 +156,10 @@ namespace Resource
osg::ref_ptr<SceneUtil::KeyframeHolder> loaded(new SceneUtil::KeyframeHolder); osg::ref_ptr<SceneUtil::KeyframeHolder> loaded(new SceneUtil::KeyframeHolder);
if (Misc::getFileExtension(normalized) == "kf") if (Misc::getFileExtension(normalized) == "kf")
{ {
NifOsg::Loader::loadKf( auto file = std::make_shared<Nif::NIFFile>(normalized);
Nif::NIFFilePtr(new Nif::NIFFile(mVFS->getNormalized(normalized), normalized)), *loaded.get()); Nif::Reader reader(*file);
reader.parse(mVFS->getNormalized(normalized));
NifOsg::Loader::loadKf(std::move(file), *loaded.get());
} }
else else
{ {

View file

@ -45,7 +45,9 @@ namespace Resource
return static_cast<NifFileHolder*>(obj.get())->mNifFile; return static_cast<NifFileHolder*>(obj.get())->mNifFile;
else else
{ {
Nif::NIFFilePtr file(new Nif::NIFFile(mVFS->get(name), name)); auto file = std::make_shared<Nif::NIFFile>(name);
Nif::Reader reader(*file);
reader.parse(mVFS->get(name));
obj = new NifFileHolder(file); obj = new NifFileHolder(file);
mCache->addEntryToObjectCache(name, obj); mCache->addEntryToObjectCache(name, obj);
return file; return file;