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())
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;
if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0))
{
numUVs = nif->getUShort();
// In Morrowind this field only corresponds to the number of UV sets.
// NifTools research is inaccurate.
if (nif->getVersion() > NIFFile::NIFVersion::VER_MW)
numUVs &= 0x3f;
// In Morrowind this field only corresponds to the number of UV sets.
// In later games only the first 6 bits are used as a count and the rest are flags.
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;
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)

@ -160,7 +160,7 @@ void NIFFile::parse(Files::IStreamPtr stream)
userVer = nif.getUInt();
// Number of records
size_t recNum = nif.getUInt();
unsigned int recNum = nif.getUInt();
records.resize(recNum);
// 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);
for(size_t i = 0;i < recNum;i++)
for (unsigned int i = 0; i < recNum; i++)
{
Record *r = nullptr;
@ -253,11 +253,11 @@ void NIFFile::parse(Files::IStreamPtr stream)
r->read(&nif);
}
size_t rootNum = nif.getUInt();
unsigned int rootNum = nif.getUInt();
roots.resize(rootNum);
//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();
if (idx >= 0 && idx < int(records.size()))

@ -116,11 +116,11 @@ enum RecordType
struct Record
{
// Record type and type name
int recType;
int recType{RC_MISSING};
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
virtual void read(NIFStream *nif) = 0;

@ -43,7 +43,6 @@
#include <components/sceneutil/morphgeometry.hpp>
#include "matrixtransform.hpp"
#include "nodeindexholder.hpp"
#include "particle.hpp"
namespace
@ -527,7 +526,7 @@ namespace NifOsg
// - finding the correct emitter node for a particle system
// - establishing connections to the animated collision shapes, which are handled in a separate loader
// - 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)
{

@ -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/data.hpp>
#include "nodeindexholder.hpp"
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)
, mFound(nullptr)
, mRecIndex(recIndex)
@ -381,19 +379,16 @@ void FindGroupByRecIndex::apply(osg::Geometry &node)
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));
if (holder && holder->getIndex() == mRecIndex)
{
osg::Group* group = searchNode.asGroup();
if (!group)
group = searchNode.getParent(0);
osg::Group* group = searchNode.asGroup();
if (!group)
group = searchNode.getParent(0);
mFound = group;
mFoundPath = getNodePath();
return;
}
mFound = group;
mFoundPath = getNodePath();
return;
}
traverse(searchNode);
}

@ -204,7 +204,7 @@ namespace NifOsg
class FindGroupByRecIndex : public osg::NodeVisitor
{
public:
FindGroupByRecIndex(int recIndex);
FindGroupByRecIndex(unsigned int recIndex);
void apply(osg::Node &node) override;
@ -218,7 +218,7 @@ namespace NifOsg
osg::Group* mFound;
osg::NodePath mFoundPath;
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.

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

Loading…
Cancel
Save