NIF fixes and cleanup

Get rid of NodeIndexHolder
Use unsigned 32-bit type for NIF record index
Fix calculation of the number of UV sets
pull/3024/head
Alexei Dobrohotov 4 years ago
parent a78aa6b22c
commit 4fc5e22e9e

@ -67,19 +67,18 @@ void NiGeometryData::read(NIFStream *nif)
if (nif->getBoolean()) if (nif->getBoolean())
nif->getVector4s(colors, verts); nif->getVector4s(colors, verts);
// Only the first 6 bits are used as a count. I think the rest are
// flags of some sort.
unsigned int numUVs = dataFlags; unsigned int numUVs = dataFlags;
if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0)) if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0))
{
numUVs = nif->getUShort(); numUVs = nif->getUShort();
// In Morrowind this field only corresponds to the number of UV sets.
// NifTools research is inaccurate. // In Morrowind this field only corresponds to the number of UV sets.
if (nif->getVersion() > NIFFile::NIFVersion::VER_MW) // In later games only the first 6 bits are used as a count and the rest are flags.
numUVs &= 0x3f; if (nif->getVersion() > NIFFile::NIFVersion::VER_MW)
{
numUVs &= 0x3f;
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0)
numUVs &= 0x1;
} }
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0)
numUVs &= 0x1;
bool hasUVs = true; bool hasUVs = true;
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW) if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)

@ -160,7 +160,7 @@ void NIFFile::parse(Files::IStreamPtr stream)
userVer = nif.getUInt(); userVer = nif.getUInt();
// Number of records // Number of records
size_t recNum = nif.getUInt(); unsigned int recNum = nif.getUInt();
records.resize(recNum); records.resize(recNum);
// Bethesda stream header // Bethesda stream header
@ -212,7 +212,7 @@ void NIFFile::parse(Files::IStreamPtr stream)
} }
const bool hasRecordSeparators = ver >= NIFStream::generateVersion(10,0,0,0) && ver < NIFStream::generateVersion(10,2,0,0); const bool hasRecordSeparators = ver >= NIFStream::generateVersion(10,0,0,0) && ver < NIFStream::generateVersion(10,2,0,0);
for(size_t i = 0;i < recNum;i++) for (unsigned int i = 0; i < recNum; i++)
{ {
Record *r = nullptr; Record *r = nullptr;
@ -253,11 +253,11 @@ void NIFFile::parse(Files::IStreamPtr stream)
r->read(&nif); r->read(&nif);
} }
size_t rootNum = nif.getUInt(); unsigned int rootNum = nif.getUInt();
roots.resize(rootNum); roots.resize(rootNum);
//Determine which records are roots //Determine which records are roots
for(size_t i = 0;i < rootNum;i++) for (unsigned int i = 0; i < rootNum; i++)
{ {
int idx = nif.getInt(); int idx = nif.getInt();
if (idx >= 0 && idx < int(records.size())) if (idx >= 0 && idx < int(records.size()))

@ -116,11 +116,11 @@ enum RecordType
struct Record struct Record
{ {
// Record type and type name // Record type and type name
int recType; int recType{RC_MISSING};
std::string recName; std::string recName;
size_t recIndex; unsigned int recIndex{~0u};
Record() : recType(RC_MISSING), recIndex(~(size_t)0) {} Record() = default;
/// Parses the record from file /// Parses the record from file
virtual void read(NIFStream *nif) = 0; virtual void read(NIFStream *nif) = 0;

@ -43,7 +43,6 @@
#include <components/sceneutil/morphgeometry.hpp> #include <components/sceneutil/morphgeometry.hpp>
#include "matrixtransform.hpp" #include "matrixtransform.hpp"
#include "nodeindexholder.hpp"
#include "particle.hpp" #include "particle.hpp"
namespace namespace
@ -527,7 +526,7 @@ namespace NifOsg
// - finding the correct emitter node for a particle system // - finding the correct emitter node for a particle system
// - establishing connections to the animated collision shapes, which are handled in a separate loader // - establishing connections to the animated collision shapes, which are handled in a separate loader
// - finding a random child NiNode in NiBspArrayController // - finding a random child NiNode in NiBspArrayController
node->getOrCreateUserDataContainer()->addUserObject(new NodeIndexHolder(nifNode->recIndex)); node->setUserValue("recIndex", nifNode->recIndex);
for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next) for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next)
{ {

@ -1,35 +0,0 @@
#ifndef OPENMW_COMPONENTS_NIFOSG_NODEINDEXHOLDER_H
#define OPENMW_COMPONENTS_NIFOSG_NODEINDEXHOLDER_H
#include <osg/Object>
namespace NifOsg
{
class NodeIndexHolder : public osg::Object
{
public:
NodeIndexHolder() = default;
NodeIndexHolder(int index)
: mIndex(index)
{
}
NodeIndexHolder(const NodeIndexHolder& copy, const osg::CopyOp& copyop)
: Object(copy, copyop)
, mIndex(copy.mIndex)
{
}
META_Object(NifOsg, NodeIndexHolder)
int getIndex() const { return mIndex; }
private:
// NIF record index
int mIndex{0};
};
}
#endif

@ -11,8 +11,6 @@
#include <components/nif/controlled.hpp> #include <components/nif/controlled.hpp>
#include <components/nif/data.hpp> #include <components/nif/data.hpp>
#include "nodeindexholder.hpp"
namespace NifOsg namespace NifOsg
{ {
@ -357,7 +355,7 @@ void Emitter::emitParticles(double dt)
} }
} }
FindGroupByRecIndex::FindGroupByRecIndex(int recIndex) FindGroupByRecIndex::FindGroupByRecIndex(unsigned int recIndex)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mFound(nullptr) , mFound(nullptr)
, mRecIndex(recIndex) , mRecIndex(recIndex)
@ -381,19 +379,16 @@ void FindGroupByRecIndex::apply(osg::Geometry &node)
void FindGroupByRecIndex::applyNode(osg::Node &searchNode) void FindGroupByRecIndex::applyNode(osg::Node &searchNode)
{ {
if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) unsigned int recIndex;
if (searchNode.getUserValue("recIndex", recIndex) && mRecIndex == recIndex)
{ {
NodeIndexHolder* holder = dynamic_cast<NodeIndexHolder*>(searchNode.getUserDataContainer()->getUserObject(0)); osg::Group* group = searchNode.asGroup();
if (holder && holder->getIndex() == mRecIndex) if (!group)
{ group = searchNode.getParent(0);
osg::Group* group = searchNode.asGroup();
if (!group)
group = searchNode.getParent(0);
mFound = group; mFound = group;
mFoundPath = getNodePath(); mFoundPath = getNodePath();
return; return;
}
} }
traverse(searchNode); traverse(searchNode);
} }

@ -204,7 +204,7 @@ namespace NifOsg
class FindGroupByRecIndex : public osg::NodeVisitor class FindGroupByRecIndex : public osg::NodeVisitor
{ {
public: public:
FindGroupByRecIndex(int recIndex); FindGroupByRecIndex(unsigned int recIndex);
void apply(osg::Node &node) override; void apply(osg::Node &node) override;
@ -218,7 +218,7 @@ namespace NifOsg
osg::Group* mFound; osg::Group* mFound;
osg::NodePath mFoundPath; osg::NodePath mFoundPath;
private: private:
int mRecIndex; unsigned int mRecIndex;
}; };
// Subclass emitter to support randomly choosing one of the child node's transforms for the emit position of new particles. // Subclass emitter to support randomly choosing one of the child node's transforms for the emit position of new particles.

@ -144,7 +144,6 @@ void registerSerializers()
"NifOsg::UpdateMorphGeometry", "NifOsg::UpdateMorphGeometry",
"NifOsg::UVController", "NifOsg::UVController",
"NifOsg::VisController", "NifOsg::VisController",
"NifOsg::NodeIndexHolder",
"osgMyGUI::Drawable", "osgMyGUI::Drawable",
"osg::DrawCallback", "osg::DrawCallback",
"osgOQ::ClearQueriesCallback", "osgOQ::ClearQueriesCallback",

Loading…
Cancel
Save