|
|
|
#include "../nif/node.hpp"
|
|
|
|
|
|
|
|
#include <components/nif/node.hpp>
|
|
|
|
#include <components/nif/property.hpp>
|
|
|
|
#include <components/nifosg/nifloader.hpp>
|
|
|
|
#include <components/resource/bgsmfilemanager.hpp>
|
|
|
|
#include <components/resource/imagemanager.hpp>
|
|
|
|
#include <components/sceneutil/serialize.hpp>
|
|
|
|
#include <components/vfs/manager.hpp>
|
|
|
|
|
|
|
|
#include <gmock/gmock.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
#include <osgDB/Registry>
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <limits>
|
|
|
|
#include <sstream>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <string>
|
|
|
|
#include <string_view>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
using namespace testing;
|
|
|
|
using namespace NifOsg;
|
|
|
|
using namespace Nif::Testing;
|
|
|
|
|
|
|
|
constexpr VFS::Path::NormalizedView testNif("test.nif");
|
|
|
|
|
|
|
|
struct BaseNifOsgLoaderTest
|
|
|
|
{
|
|
|
|
VFS::Manager mVfs;
|
|
|
|
Resource::ImageManager mImageManager{ &mVfs, 0 };
|
|
|
|
Resource::BgsmFileManager mMaterialManager{ &mVfs, 0 };
|
|
|
|
const osgDB::ReaderWriter* mReaderWriter = osgDB::Registry::instance()->getReaderWriterForExtension("osgt");
|
|
|
|
osg::ref_ptr<osgDB::Options> 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;
|
|
|
|
line.erase(line.find_last_not_of(" \t\n\r\f\v") + 1);
|
|
|
|
result += line;
|
|
|
|
result += '\n';
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NifOsgLoaderTest : Test, BaseNifOsgLoaderTest
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(NifOsgLoaderTest, shouldLoadFileWithDefaultNode)
|
|
|
|
{
|
|
|
|
Nif::NiAVObject node;
|
|
|
|
init(node);
|
|
|
|
Nif::NIFFile file(testNif);
|
|
|
|
file.mRoots.push_back(&node);
|
|
|
|
auto result = Loader::load(file, &mImageManager, &mMaterialManager);
|
|
|
|
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 formatOsgNodeForBSShaderProperty(std::string_view shaderPrefix)
|
|
|
|
{
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << 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 ")"
|
|
|
|
<< shaderPrefix << R"("
|
|
|
|
}
|
|
|
|
osg::BoolValueObject {
|
|
|
|
UniqueID 8
|
|
|
|
Name "shaderRequired"
|
|
|
|
Value TRUE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
StateSet TRUE {
|
|
|
|
osg::StateSet {
|
|
|
|
UniqueID 9
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)";
|
|
|
|
return oss.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string formatOsgNodeForBSLightingShaderProperty(std::string_view shaderPrefix)
|
|
|
|
{
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << 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 ")"
|
|
|
|
<< shaderPrefix << R"("
|
|
|
|
}
|
|
|
|
osg::BoolValueObject {
|
|
|
|
UniqueID 8
|
|
|
|
Name "shaderRequired"
|
|
|
|
Value TRUE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
StateSet TRUE {
|
|
|
|
osg::StateSet {
|
|
|
|
UniqueID 9
|
|
|
|
ModeList 1 {
|
|
|
|
GL_DEPTH_TEST ON
|
|
|
|
}
|
|
|
|
AttributeList 1 {
|
|
|
|
osg::Depth {
|
|
|
|
UniqueID 10
|
|
|
|
Function LEQUAL
|
|
|
|
}
|
|
|
|
Value OFF
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)";
|
|
|
|
return oss.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ShaderPrefixParams
|
|
|
|
{
|
|
|
|
unsigned int mShaderType;
|
|
|
|
std::string_view mExpectedShaderPrefix;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NifOsgLoaderBSShaderPrefixTest : TestWithParam<ShaderPrefixParams>, BaseNifOsgLoaderTest
|
|
|
|
{
|
|
|
|
static constexpr std::array sParams = {
|
|
|
|
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_Default), "bs/default" },
|
|
|
|
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_NoLighting), "bs/nolighting" },
|
|
|
|
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_Tile), "bs/default" },
|
|
|
|
ShaderPrefixParams{ std::numeric_limits<unsigned int>::max(), "bs/default" },
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_P(NifOsgLoaderBSShaderPrefixTest, shouldAddShaderPrefix)
|
|
|
|
{
|
|
|
|
Nif::NiAVObject node;
|
|
|
|
init(node);
|
|
|
|
Nif::BSShaderPPLightingProperty property;
|
|
|
|
property.recType = Nif::RC_BSShaderPPLightingProperty;
|
|
|
|
property.mTextureSet = nullptr;
|
|
|
|
property.mController = nullptr;
|
|
|
|
property.mType = GetParam().mShaderType;
|
|
|
|
node.mProperties.push_back(Nif::RecordPtrT<Nif::NiProperty>(&property));
|
|
|
|
Nif::NIFFile file(testNif);
|
|
|
|
file.mRoots.push_back(&node);
|
|
|
|
auto result = Loader::load(file, &mImageManager, &mMaterialManager);
|
|
|
|
EXPECT_EQ(serialize(*result), formatOsgNodeForBSShaderProperty(GetParam().mExpectedShaderPrefix));
|
|
|
|
}
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_SUITE_P(Params, NifOsgLoaderBSShaderPrefixTest, ValuesIn(NifOsgLoaderBSShaderPrefixTest::sParams));
|
|
|
|
|
|
|
|
struct NifOsgLoaderBSLightingShaderPrefixTest : TestWithParam<ShaderPrefixParams>, BaseNifOsgLoaderTest
|
|
|
|
{
|
|
|
|
static constexpr std::array sParams = {
|
|
|
|
ShaderPrefixParams{
|
|
|
|
static_cast<unsigned int>(Nif::BSLightingShaderType::ShaderType_Default), "bs/default" },
|
|
|
|
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSLightingShaderType::ShaderType_Cloud), "bs/default" },
|
|
|
|
ShaderPrefixParams{ std::numeric_limits<unsigned int>::max(), "bs/default" },
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_P(NifOsgLoaderBSLightingShaderPrefixTest, shouldAddShaderPrefix)
|
|
|
|
{
|
|
|
|
Nif::NiAVObject node;
|
|
|
|
init(node);
|
|
|
|
Nif::BSLightingShaderProperty property;
|
|
|
|
property.recType = Nif::RC_BSLightingShaderProperty;
|
|
|
|
property.mTextureSet = nullptr;
|
|
|
|
property.mController = nullptr;
|
|
|
|
property.mType = GetParam().mShaderType;
|
|
|
|
property.mShaderFlags1 |= Nif::BSShaderFlags1::BSSFlag1_DepthTest;
|
|
|
|
property.mShaderFlags2 |= Nif::BSShaderFlags2::BSSFlag2_DepthWrite;
|
|
|
|
node.mProperties.push_back(Nif::RecordPtrT<Nif::NiProperty>(&property));
|
|
|
|
Nif::NIFFile file(testNif);
|
|
|
|
file.mRoots.push_back(&node);
|
|
|
|
auto result = Loader::load(file, &mImageManager, &mMaterialManager);
|
|
|
|
EXPECT_EQ(serialize(*result), formatOsgNodeForBSLightingShaderProperty(GetParam().mExpectedShaderPrefix));
|
|
|
|
}
|
|
|
|
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
|
|
Params, NifOsgLoaderBSLightingShaderPrefixTest, ValuesIn(NifOsgLoaderBSLightingShaderPrefixTest::sParams));
|
|
|
|
}
|