#include "../nif/node.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { using namespace testing; using namespace NifOsg; using namespace Nif::Testing; struct BaseNifOsgLoaderTest { VFS::Manager mVfs{ false }; Resource::ImageManager mImageManager{ &mVfs }; const osgDB::ReaderWriter* mReaderWriter = osgDB::Registry::instance()->getReaderWriterForExtension("osgt"); osg::ref_ptr mOptions = new osgDB::Options; BaseNifOsgLoaderTest() { SceneUtil::registerSerializers(); if (mReaderWriter == nullptr) throw std::runtime_error("osgt reader writer is not found"); mOptions->setPluginStringData("fileType", "Ascii"); mOptions->setPluginStringData("WriteImageHint", "UseExternal"); } std::string serialize(const osg::Node& node) const { std::stringstream stream; mReaderWriter->writeNode(node, stream, mOptions); std::string result; for (std::string line; std::getline(stream, line);) { if (line.starts_with('#')) continue; boost::trim_right(line); result += line; result += '\n'; } return result; } }; struct NifOsgLoaderTest : Test, BaseNifOsgLoaderTest { }; TEST_F(NifOsgLoaderTest, shouldLoadFileWithDefaultNode) { Nif::Node node; init(node); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&node); auto result = Loader::load(file, &mImageManager); EXPECT_EQ(serialize(*result), R"( osg::Group { UniqueID 1 DataVariance STATIC UserDataContainer TRUE { osg::DefaultUserDataContainer { UniqueID 2 UDC_UserObjects 1 { osg::StringValueObject { UniqueID 3 Name "fileHash" } } } } Children 1 { osg::Group { UniqueID 4 DataVariance STATIC UserDataContainer TRUE { osg::DefaultUserDataContainer { UniqueID 5 UDC_UserObjects 1 { osg::UIntValueObject { UniqueID 6 Name "recIndex" Value 4294967295 } } } } } } } )"); } std::string formatOsgNodeForShaderProperty(std::string_view shaderPrefix) { static constexpr const char format[] = R"( osg::Group { UniqueID 1 DataVariance STATIC UserDataContainer TRUE { osg::DefaultUserDataContainer { UniqueID 2 UDC_UserObjects 1 { osg::StringValueObject { UniqueID 3 Name "fileHash" } } } } Children 1 { osg::Group { UniqueID 4 DataVariance STATIC UserDataContainer TRUE { osg::DefaultUserDataContainer { UniqueID 5 UDC_UserObjects 3 { osg::UIntValueObject { UniqueID 6 Name "recIndex" Value 4294967295 } osg::StringValueObject { UniqueID 7 Name "shaderPrefix" Value "%s" } osg::BoolValueObject { UniqueID 8 Name "shaderRequired" Value TRUE } } } } StateSet TRUE { osg::StateSet { UniqueID 9 } } } } } )"; return (boost::format(format) % shaderPrefix).str(); } struct ShaderPrefixParams { unsigned int mShaderType; std::string_view mExpectedShaderPrefix; }; struct NifOsgLoaderBSShaderPrefixTest : TestWithParam, BaseNifOsgLoaderTest { static constexpr std::array sParams = { ShaderPrefixParams{ static_cast(Nif::BSShaderType::ShaderType_Default), "bs/default" }, ShaderPrefixParams{ static_cast(Nif::BSShaderType::ShaderType_NoLighting), "bs/nolighting" }, ShaderPrefixParams{ static_cast(Nif::BSShaderType::ShaderType_Tile), "bs/default" }, ShaderPrefixParams{ std::numeric_limits::max(), "bs/default" }, }; }; TEST_P(NifOsgLoaderBSShaderPrefixTest, shouldAddShaderPrefix) { Nif::Node node; init(node); Nif::BSShaderPPLightingProperty property; property.recType = Nif::RC_BSShaderPPLightingProperty; property.textureSet = nullptr; property.controller = nullptr; property.type = GetParam().mShaderType; node.props.push_back(Nif::RecordPtrT(&property)); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&node); auto result = Loader::load(file, &mImageManager); EXPECT_EQ(serialize(*result), formatOsgNodeForShaderProperty(GetParam().mExpectedShaderPrefix)); } INSTANTIATE_TEST_SUITE_P(Params, NifOsgLoaderBSShaderPrefixTest, ValuesIn(NifOsgLoaderBSShaderPrefixTest::sParams)); struct NifOsgLoaderBSLightingShaderPrefixTest : TestWithParam, BaseNifOsgLoaderTest { static constexpr std::array sParams = { ShaderPrefixParams{ static_cast(Nif::BSLightingShaderType::ShaderType_Default), "bs/default" }, ShaderPrefixParams{ static_cast(Nif::BSLightingShaderType::ShaderType_Cloud), "bs/default" }, ShaderPrefixParams{ std::numeric_limits::max(), "bs/default" }, }; }; TEST_P(NifOsgLoaderBSLightingShaderPrefixTest, shouldAddShaderPrefix) { Nif::Node node; init(node); Nif::BSLightingShaderProperty property; property.recType = Nif::RC_BSLightingShaderProperty; property.mTextureSet = nullptr; property.controller = nullptr; property.type = GetParam().mShaderType; node.props.push_back(Nif::RecordPtrT(&property)); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&node); auto result = Loader::load(file, &mImageManager); EXPECT_EQ(serialize(*result), formatOsgNodeForShaderProperty(GetParam().mExpectedShaderPrefix)); } INSTANTIATE_TEST_SUITE_P( Params, NifOsgLoaderBSLightingShaderPrefixTest, ValuesIn(NifOsgLoaderBSLightingShaderPrefixTest::sParams)); }