Some more minor NIF support fixes

pull/2689/head
Capostrophic 5 years ago
parent 9b21249a9e
commit e363d5df21

@ -59,7 +59,7 @@ public:
controller.post(nif); controller.post(nif);
} }
}; };
typedef Named NiSequenceStreamHelper; using NiSequenceStreamHelper = Named;
} // Namespace } // Namespace
#endif #endif

@ -10,17 +10,18 @@ namespace Nif
Named::read(nif); Named::read(nif);
external = nif->getChar() != 0; external = nif->getChar() != 0;
bool internal = false;
if (external) if (external)
filename = nif->getString(); filename = nif->getString();
else else
{ internal = nif->getChar();
nif->getChar(); // always 1
if (!external && internal)
data.read(nif); data.read(nif);
}
pixel = nif->getInt(); pixel = nif->getUInt();
mipmap = nif->getInt(); mipmap = nif->getUInt();
alpha = nif->getInt(); alpha = nif->getUInt();
nif->getChar(); // always 1 nif->getChar(); // always 1
} }
@ -113,8 +114,4 @@ namespace Nif
mCenter = nif->getVector3(); mCenter = nif->getVector3();
} }
} }

@ -46,13 +46,13 @@ public:
3 - Compressed 3 - Compressed
4 - Bumpmap 4 - Bumpmap
5 - Default */ 5 - Default */
int pixel; unsigned int pixel;
/* Mipmap format /* Mipmap format
0 - no 0 - no
1 - yes 1 - yes
2 - default */ 2 - default */
int mipmap; unsigned int mipmap;
/* Alpha /* Alpha
0 - none 0 - none
@ -60,7 +60,7 @@ public:
2 - smooth 2 - smooth
3 - default (use material alpha, or multiply material with texture if present) 3 - default (use material alpha, or multiply material with texture if present)
*/ */
int alpha; unsigned int alpha;
void read(NIFStream *nif); void read(NIFStream *nif);
void post(NIFFile *nif); void post(NIFFile *nif);

@ -92,6 +92,12 @@ namespace Nif
void NiMaterialColorController::read(NIFStream *nif) void NiMaterialColorController::read(NIFStream *nif)
{ {
Controller::read(nif); Controller::read(nif);
// Two bits that correspond to the controlled material color.
// 00: Ambient
// 01: Diffuse
// 10: Specular
// 11: Emissive
targetColor = (flags >> 4) & 3;
data.read(nif); data.read(nif);
} }
@ -189,7 +195,8 @@ namespace Nif
{ {
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
nif->getChar(); // always 0 if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
/*bool alwaysActive = */nif->getChar(); // Always 0
} }
void NiGeomMorpherController::post(NIFFile *nif) void NiGeomMorpherController::post(NIFFile *nif)

@ -78,12 +78,13 @@ public:
void read(NIFStream *nif); void read(NIFStream *nif);
void post(NIFFile *nif); void post(NIFFile *nif);
}; };
typedef NiParticleSystemController NiBSPArrayController; using NiBSPArrayController = NiParticleSystemController;
class NiMaterialColorController : public Controller class NiMaterialColorController : public Controller
{ {
public: public:
NiPosDataPtr data; NiPosDataPtr data;
unsigned int targetColor;
void read(NIFStream *nif); void read(NIFStream *nif);
void post(NIFFile *nif); void post(NIFFile *nif);

@ -225,7 +225,8 @@ void NiSkinData::read(NIFStream *nif)
trafo.scale = nif->getFloat(); trafo.scale = nif->getFloat();
int boneNum = nif->getInt(); int boneNum = nif->getInt();
nif->getInt(); // -1 if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW && nif->getVersion() <= NIFFile::NIFVersion::VER_GAMEBRYO)
nif->skip(4); // NiSkinPartition link
bones.resize(boneNum); bones.resize(boneNum);
for (BoneInfo &bi : bones) for (BoneInfo &bi : bones)

@ -143,7 +143,7 @@ void NIFFile::parse(Files::IStreamPtr stream)
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 != VER_4_0_0_0 && ver != VER_MW) if(ver != nif.generateVersion(4,0,0,0) && ver != VER_MW)
fail("Unsupported NIF version: " + printVersion(ver)); fail("Unsupported NIF version: " + printVersion(ver));
// Number of records // Number of records
size_t recNum = nif.getInt(); size_t recNum = nif.getInt();

@ -75,26 +75,16 @@ class NIFFile final : public File
void operator = (NIFFile const &); void operator = (NIFFile const &);
public: public:
// For generic versions NIFStream::generateVersion() is used instead
enum NIFVersion enum NIFVersion
{ {
// Feature-relevant VER_MW = 0x04000002, // 4.0.0.2. Main Morrowind NIF version.
VER_4_1_0_0 = 0x04010000, // 1-byte booleans (previously 4-byte) VER_CI = 0x04020200, // 4.2.2.0. Main Culpa Innata NIF version, also used in Civ4.
VER_5_0_0_1 = 0x05000001, // Optimized record type listings VER_ZT2 = 0x0A000100, // 10.0.1.0. Main Zoo Tycoon 2 NIF version, also used in Oblivion and Civ4.
VER_5_0_0_6 = 0x05000006, // Record groups VER_OB_OLD = 0x0A000102, // 10.0.1.2. Main older Oblivion NIF version.
VER_10_0_1_8 = 0x0A000108, // The last version without user version
VER_20_1_0_1 = 0x14010001, // String tables
VER_20_2_0_5 = 0x14020005, // Record sizes
// Game-relevant
VER_4_0_0_0 = 0x04000000, // Freedom Force NIFs, supported by Morrowind
VER_MW = 0x04000002, // 4.0.0.2. Morrowind and Freedom Force NIFs
VER_4_2_1_0 = 0x04020100, // Used in Civ4 and Dark Age of Camelot
VER_CI = 0x04020200, // 4.2.2.0. Main Culpa Innata NIF version, also used in Civ4
VER_ZT2 = 0x0A000100, // 10.0.1.0. Main Zoo Tycoon 2 NIF version, also used in Oblivion and Civ4
VER_OB_OLD = 0x0A000102, // 10.0.1.2. Main older Oblivion NIF version
VER_GAMEBRYO = 0x0A010000, // 10.1.0.0. Lots of games use it. The first version that has Gamebryo File Format header. VER_GAMEBRYO = 0x0A010000, // 10.1.0.0. Lots of games use it. The first version that has Gamebryo File Format header.
VER_10_2_0_0 = 0x0A020000, // Lots of games use this version as well.
VER_CIV4 = 0x14000004, // 20.0.0.4. Main Civilization IV NIF version. VER_CIV4 = 0x14000004, // 20.0.0.4. Main Civilization IV NIF version.
VER_OB = 0x14000005, // 20.0.0.5. Main Oblivion NIF version VER_OB = 0x14000005, // 20.0.0.5. Main Oblivion NIF version.
VER_BGS = 0x14020007 // 20.2.0.7. Main Fallout 3/4/76/New Vegas and Skyrim/SkyrimSE NIF version. VER_BGS = 0x14020007 // 20.2.0.7. Main Fallout 3/4/76/New Vegas and Skyrim/SkyrimSE NIF version.
}; };
enum BethVersion enum BethVersion

@ -163,6 +163,12 @@ public:
unsigned int getUserVersion(); unsigned int getUserVersion();
unsigned int getBethVersion(); unsigned int getBethVersion();
// Convert human-readable version numbers into a number that can be compared.
uint32_t generateVersion(uint8_t major, uint8_t minor, uint8_t patch, uint8_t rev)
{
return (major << 24) + (minor << 16) + (patch << 8) + rev;
}
///Read in a string of the given length ///Read in a string of the given length
std::string getSizedString(size_t length) std::string getSizedString(size_t length)
{ {

@ -284,6 +284,7 @@ struct NiLODNode : public NiSwitchNode
void read(NIFStream *nif) void read(NIFStream *nif)
{ {
NiSwitchNode::read(nif); NiSwitchNode::read(nif);
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW && nif->getVersion() <= NIFFile::NIFVersion::VER_ZT2)
lodCenter = nif->getVector3(); lodCenter = nif->getVector3();
unsigned int numLodLevels = nif->getUInt(); unsigned int numLodLevels = nif->getUInt();
for (unsigned int i=0; i<numLodLevels; ++i) for (unsigned int i=0; i<numLodLevels; ++i)

@ -768,12 +768,7 @@ namespace NifOsg
const Nif::NiMaterialColorController* matctrl = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr()); const Nif::NiMaterialColorController* matctrl = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr());
if (matctrl->data.empty()) if (matctrl->data.empty())
continue; continue;
// Two bits that correspond to the controlled material color. auto targetColor = static_cast<MaterialColorController::TargetColor>(matctrl->targetColor);
// 00: Ambient
// 01: Diffuse
// 10: Specular
// 11: Emissive
MaterialColorController::TargetColor targetColor = static_cast<MaterialColorController::TargetColor>((matctrl->flags >> 4) & 3);
osg::ref_ptr<MaterialColorController> osgctrl(new MaterialColorController(matctrl->data.getPtr(), targetColor)); osg::ref_ptr<MaterialColorController> osgctrl(new MaterialColorController(matctrl->data.getPtr(), targetColor));
setupController(matctrl, osgctrl, animflags); setupController(matctrl, osgctrl, animflags);
composite->addController(osgctrl); composite->addController(osgctrl);

Loading…
Cancel
Save