mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-27 04:40:26 +00:00
Allow loading arbitrary NIF files
This commit is contained in:
parent
f6b43b9321
commit
7e63afdecf
4 changed files with 73 additions and 3 deletions
|
@ -1,9 +1,12 @@
|
||||||
#include "niffile.hpp"
|
#include "niffile.hpp"
|
||||||
#include "effect.hpp"
|
#include "effect.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -137,15 +140,46 @@ void NIFFile::parse(Files::IStreamPtr stream)
|
||||||
|
|
||||||
// Check the header string
|
// Check the header string
|
||||||
std::string head = nif.getVersionString();
|
std::string head = nif.getVersionString();
|
||||||
if(head.compare(0, 22, "NetImmerse File Format") != 0)
|
static const std::array<std::string, 2> verStrings =
|
||||||
|
{
|
||||||
|
"NetImmerse File Format",
|
||||||
|
"Gamebryo File Format"
|
||||||
|
};
|
||||||
|
bool supported = false;
|
||||||
|
for (const std::string& verString : verStrings)
|
||||||
|
{
|
||||||
|
supported = (head.compare(0, verString.size(), verString) == 0);
|
||||||
|
if (supported)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!supported)
|
||||||
fail("Invalid NIF header: " + head);
|
fail("Invalid NIF header: " + head);
|
||||||
|
|
||||||
|
supported = false;
|
||||||
|
|
||||||
// Get BCD version
|
// Get BCD version
|
||||||
ver = nif.getUInt();
|
ver = nif.getUInt();
|
||||||
// 4.0.0.0 is an older, practically identical version of the format.
|
// 4.0.0.0 is an older, practically identical version of the format.
|
||||||
// It's not used by Morrowind assets but Morrowind supports it.
|
// It's not used by Morrowind assets but Morrowind supports it.
|
||||||
if(ver != NIFStream::generateVersion(4,0,0,0) && ver != VER_MW)
|
static const std::array<uint32_t, 2> supportedVers =
|
||||||
|
{
|
||||||
|
NIFStream::generateVersion(4,0,0,0),
|
||||||
|
VER_MW
|
||||||
|
};
|
||||||
|
for (uint32_t supportedVer : supportedVers)
|
||||||
|
{
|
||||||
|
supported = (ver == supportedVer);
|
||||||
|
if (supported)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!supported)
|
||||||
|
{
|
||||||
|
static const bool ignoreUnsupported = Settings::Manager::getBool("load unsupported nif files", "Models");
|
||||||
|
if (ignoreUnsupported)
|
||||||
|
warn("Unsupported NIF version: " + printVersion(ver) + ". Proceed with caution!");
|
||||||
|
else
|
||||||
fail("Unsupported NIF version: " + printVersion(ver));
|
fail("Unsupported NIF version: " + printVersion(ver));
|
||||||
|
}
|
||||||
|
|
||||||
// NIF data endianness
|
// NIF data endianness
|
||||||
if (ver >= NIFStream::generateVersion(20,0,0,4))
|
if (ver >= NIFStream::generateVersion(20,0,0,4))
|
||||||
|
@ -245,6 +279,9 @@ void NIFFile::parse(Files::IStreamPtr stream)
|
||||||
else
|
else
|
||||||
fail("Unknown record type " + rec);
|
fail("Unknown record type " + rec);
|
||||||
|
|
||||||
|
if (!supported)
|
||||||
|
Log(Debug::Verbose) << "NIF Debug: Reading record of type " << rec << ", index " << i << " (" << filename << ")";
|
||||||
|
|
||||||
assert(r != nullptr);
|
assert(r != nullptr);
|
||||||
assert(r->recType != RC_MISSING);
|
assert(r->recType != RC_MISSING);
|
||||||
r->recName = rec;
|
r->recName = rec;
|
||||||
|
|
|
@ -58,3 +58,4 @@ The ranges included with each setting are the physically possible ranges, not re
|
||||||
windows
|
windows
|
||||||
navigator
|
navigator
|
||||||
physics
|
physics
|
||||||
|
models
|
||||||
|
|
27
docs/source/reference/modding/settings/models.rst
Normal file
27
docs/source/reference/modding/settings/models.rst
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Models Settings
|
||||||
|
###############
|
||||||
|
|
||||||
|
load unsupported nif files
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
:Type: boolean
|
||||||
|
:Range: True/False
|
||||||
|
:Default: False
|
||||||
|
|
||||||
|
At the moment OpenMW's NIF loader is only tailored to load models
|
||||||
|
that can also load in Morrowind.
|
||||||
|
|
||||||
|
However, you can enable its limited and experimental support for updates in
|
||||||
|
the definitions of record types from later NIF revisions by toggling on
|
||||||
|
this setting.
|
||||||
|
|
||||||
|
You must keep in mind that loading unsupported NIF files may fail,
|
||||||
|
and the degree of this failure may vary. In milder cases, OpenMW will reject
|
||||||
|
the file anyway because it lacks a definition for a certain record type
|
||||||
|
that the file may use. In more severe cases OpenMW's
|
||||||
|
incomplete understanding of a record type can lead to memory corruption,
|
||||||
|
crashes or even freezes. Don't enable this if you're not sure that
|
||||||
|
you know what you're doing.
|
||||||
|
|
||||||
|
To help debug possible issues OpenMW will log its progress in loading
|
||||||
|
every file that uses an unsupported NIF version.
|
|
@ -945,3 +945,8 @@ lineofsight keep inactive cache = 0
|
||||||
|
|
||||||
# Defer bounding boxes update until collision detection.
|
# Defer bounding boxes update until collision detection.
|
||||||
defer aabb update = true
|
defer aabb update = true
|
||||||
|
|
||||||
|
[Models]
|
||||||
|
# Attempt to load any valid NIF file regardless of its version and track the progress.
|
||||||
|
# Loading arbitrary meshes is not advised and may cause instability.
|
||||||
|
load unsupported nif files = false
|
||||||
|
|
Loading…
Reference in a new issue