From 0154bb78dfb300832984509696b7652343b3cff5 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Tue, 5 Sep 2023 23:19:35 +0300 Subject: [PATCH] Modernize NiSkinPartition --- components/nif/data.cpp | 92 +++++++++++++-------------------- components/nif/data.hpp | 20 +++---- components/nifosg/nifloader.cpp | 8 +-- 3 files changed, 51 insertions(+), 69 deletions(-) diff --git a/components/nif/data.cpp b/components/nif/data.cpp index 16f5822bf0..25aa0fce44 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -397,8 +397,7 @@ namespace Nif void NiSkinPartition::read(NIFStream* nif) { - nif->read(mPartitionNum); - mPartitions.resize(mPartitionNum); + mPartitions.resize(nif->get()); if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE) { @@ -417,89 +416,72 @@ namespace Nif void NiSkinPartition::Partition::read(NIFStream* nif) { - size_t numVertices = nif->getUShort(); - size_t numTriangles = nif->getUShort(); - size_t numBones = nif->getUShort(); - size_t numStrips = nif->getUShort(); - size_t bonesPerVertex = nif->getUShort(); - nif->readVector(bones, numBones); + uint16_t numVertices, numTriangles, numBones, numStrips, bonesPerVertex; + nif->read(numVertices); + nif->read(numTriangles); + nif->read(numBones); + nif->read(numStrips); + nif->read(bonesPerVertex); + nif->readVector(mBones, numBones); bool hasVertexMap = true; if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) - hasVertexMap = nif->getBoolean(); + nif->read(hasVertexMap); if (hasVertexMap) - nif->readVector(vertexMap, numVertices); + nif->readVector(mVertexMap, numVertices); bool hasVertexWeights = true; if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) - hasVertexWeights = nif->getBoolean(); + nif->read(hasVertexWeights); if (hasVertexWeights) - nif->readVector(weights, numVertices * bonesPerVertex); + nif->readVector(mWeights, numVertices * bonesPerVertex); std::vector stripLengths; nif->readVector(stripLengths, numStrips); bool hasFaces = true; if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) - hasFaces = nif->getBoolean(); + nif->read(hasFaces); if (hasFaces) { if (numStrips) { - strips.resize(numStrips); + mStrips.resize(numStrips); for (size_t i = 0; i < numStrips; i++) - nif->readVector(strips[i], stripLengths[i]); + nif->readVector(mStrips[i], stripLengths[i]); } else - nif->readVector(triangles, numTriangles * 3); + nif->readVector(mTriangles, numTriangles * 3); } - bool hasBoneIndices = nif->getChar() != 0; - if (hasBoneIndices) - nif->readVector(boneIndices, numVertices * bonesPerVertex); + if (nif->get() != 0) + nif->readVector(mBoneIndices, numVertices * bonesPerVertex); if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3) { - nif->getChar(); // LOD level - nif->getBoolean(); // Global VB + nif->read(mLODLevel); + nif->read(mGlobalVB); } if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE) { mVertexDesc.read(nif); - nif->readVector(trueTriangles, numTriangles * 3); + nif->readVector(mTrueTriangles, numTriangles * 3); + } + else if (!mVertexMap.empty()) + { + if (!mStrips.empty()) + { + mTrueStrips = mStrips; + for (auto& strip : mTrueStrips) + for (auto& index : strip) + index = mVertexMap[index]; + } + else if (!mTriangles.empty()) + { + mTrueTriangles = mTriangles; + for (unsigned short& index : mTrueTriangles) + index = mVertexMap[index]; + } } - } - - std::vector NiSkinPartition::Partition::getTrueTriangles() const - { - if (!trueTriangles.empty()) - return trueTriangles; - - std::vector remappedTriangles; - if (vertexMap.empty() || triangles.empty()) - return remappedTriangles; - - remappedTriangles = triangles; - - for (unsigned short& index : remappedTriangles) - index = vertexMap[index]; - return remappedTriangles; - } - - std::vector> NiSkinPartition::Partition::getTrueStrips() const - { - if (!trueTriangles.empty()) - return {}; - - std::vector> remappedStrips; - if (vertexMap.empty() || strips.empty()) - return remappedStrips; - - remappedStrips = strips; - for (auto& strip : remappedStrips) - for (auto& index : strip) - index = vertexMap[index]; - - return remappedStrips; } void NiMorphData::read(NIFStream* nif) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index c55dd7ffd8..025a2d524e 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -289,20 +289,20 @@ namespace Nif { struct Partition { - std::vector bones; - std::vector vertexMap; - std::vector weights; - std::vector> strips; - std::vector triangles; - std::vector trueTriangles; - std::vector boneIndices; + std::vector mBones; + std::vector mVertexMap; + std::vector mWeights; + std::vector> mStrips; + std::vector mTriangles; + std::vector mBoneIndices; BSVertexDesc mVertexDesc; + std::vector mTrueTriangles; + std::vector> mTrueStrips; + uint8_t mLODLevel; + bool mGlobalVB; void read(NIFStream* nif); - std::vector getTrueTriangles() const; - std::vector> getTrueStrips() const; }; - unsigned int mPartitionNum; std::vector mPartitions; unsigned int mDataSize; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index c748c1a6ae..acc1c2d054 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1403,18 +1403,18 @@ namespace NifOsg hasPartitions = partitions != nullptr; if (hasPartitions) { - std::vector trueTriangles; for (const Nif::NiSkinPartition::Partition& partition : partitions->mPartitions) { - trueTriangles = partition.getTrueTriangles(); + const std::vector& trueTriangles = partition.mTrueTriangles; if (!trueTriangles.empty()) { geometry->addPrimitiveSet(new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLES, trueTriangles.size(), trueTriangles.data())); } - const std::vector> trueStrips = partition.getTrueStrips(); - for (const auto& strip : trueStrips) + for (const auto& strip : partition.mTrueStrips) { + if (strip.size() < 3) + continue; geometry->addPrimitiveSet(new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(), strip.data())); }