Read NiSkinPartition

pull/3030/head
Alexei Dobrohotov 4 years ago
parent afea11b70a
commit a38c629425

@ -320,7 +320,7 @@ void NiSkinData::read(NIFStream *nif)
int boneNum = nif->getInt();
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW && nif->getVersion() <= NIFStream::generateVersion(10,1,0,0))
nif->skip(4); // NiSkinPartition link
partitions.read(nif);
// Has vertex weights flag
if (nif->getVersion() > NIFStream::generateVersion(4,2,1,0) && !nif->getBoolean())
@ -345,6 +345,69 @@ void NiSkinData::read(NIFStream *nif)
}
}
void NiSkinData::post(NIFFile *nif)
{
partitions.post(nif);
}
void NiSkinPartition::read(NIFStream *nif)
{
unsigned int num = nif->getUInt();
data.resize(num);
for (auto& partition : data)
partition.read(nif);
}
void NiSkinPartition::Partition::read(NIFStream *nif)
{
unsigned short numVertices = nif->getUShort();
unsigned short numTriangles = nif->getUShort();
unsigned short numBones = nif->getUShort();
unsigned short numStrips = nif->getUShort();
unsigned short bonesPerVertex = nif->getUShort();
if (numBones)
nif->getUShorts(bones, numBones);
bool hasVertexMap = true;
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0))
hasVertexMap = nif->getBoolean();
if (hasVertexMap && numVertices)
nif->getUShorts(vertexMap, numVertices);
bool hasVertexWeights = true;
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0))
hasVertexWeights = nif->getBoolean();
if (hasVertexWeights && numVertices && bonesPerVertex)
nif->getFloats(weights, numVertices * bonesPerVertex);
std::vector<unsigned short> stripLengths;
if (numStrips)
nif->getUShorts(stripLengths, numStrips);
bool hasFaces = true;
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0))
hasFaces = nif->getBoolean();
if (hasFaces)
{
if (numStrips)
{
strips.resize(numStrips);
for (unsigned short i = 0; i < numStrips; i++)
nif->getUShorts(strips[i], stripLengths[i]);
}
else if (numTriangles)
nif->getUShorts(triangles, numTriangles * 3);
}
bool hasBoneIndices = nif->getChar() != 0;
if (hasBoneIndices && numVertices && bonesPerVertex)
nif->getChars(boneIndices, numVertices * bonesPerVertex);
if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
{
nif->getChar(); // LOD level
nif->getBoolean(); // Global VB
}
}
void NiMorphData::read(NIFStream *nif)
{
int morphCount = nif->getInt();

@ -174,6 +174,7 @@ class NiSkinInstance : public Record
{
public:
NiSkinDataPtr data;
NiSkinPartitionPtr partitions;
NodePtr root;
NodeList bones;
@ -200,6 +201,25 @@ public:
Transformation trafo;
std::vector<BoneInfo> bones;
NiSkinPartitionPtr partitions;
void read(NIFStream *nif) override;
void post(NIFFile *nif) override;
};
struct NiSkinPartition : public Record
{
struct Partition
{
std::vector<unsigned short> bones;
std::vector<unsigned short> vertexMap;
std::vector<float> weights;
std::vector<std::vector<unsigned short>> strips;
std::vector<unsigned short> triangles;
std::vector<char> boneIndices;
void read(NIFStream *nif);
};
std::vector<Partition> data;
void read(NIFStream *nif) override;
};

@ -118,6 +118,7 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
factory["NiFloatsExtraData"] = {&construct <NiFloatsExtraData> , RC_NiFloatsExtraData };
factory["NiStringPalette"] = {&construct <NiStringPalette> , RC_NiStringPalette };
factory["NiBoolData"] = {&construct <NiBoolData> , RC_NiBoolData };
factory["NiSkinPartition"] = {&construct <NiSkinPartition> , RC_NiSkinPartition };
return factory;
}

@ -111,7 +111,8 @@ enum RecordType
RC_NiFloatExtraData,
RC_NiFloatsExtraData,
RC_NiStringPalette,
RC_NiBoolData
RC_NiBoolData,
RC_NiSkinPartition
};
/// Base class for all records

@ -144,6 +144,7 @@ class NiPalette;
struct NiParticleModifier;
struct NiLinesData;
struct NiBoolData;
struct NiSkinPartition;
using NodePtr = RecordPtrT<Node>;
using ExtraPtr = RecordPtrT<Extra>;
@ -168,6 +169,7 @@ using NiAutoNormalParticlesDataPtr = RecordPtrT<NiAutoNormalParticlesData>;
using NiPalettePtr = RecordPtrT<NiPalette>;
using NiParticleModifierPtr = RecordPtrT<NiParticleModifier>;
using NiBoolDataPtr = RecordPtrT<NiBoolData>;
using NiSkinPartitionPtr = RecordPtrT<NiSkinPartition>;
using NodeList = RecordListT<Node>;
using PropertyList = RecordListT<Property>;

Loading…
Cancel
Save