1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-20 20:53:06 +00:00

Reserve capacity for node NIF collections

This commit is contained in:
Alexei Kotov 2025-12-14 22:17:29 +03:00
parent 7332b4e232
commit 02d9c26289
2 changed files with 43 additions and 47 deletions

View file

@ -63,6 +63,16 @@ namespace
namespace Nif namespace Nif
{ {
namespace
{
void readBSDistantObjectInstanceTransform(NIFStream& stream, osg::Matrixf& value)
{
std::array<float, 16> mat;
stream.readArray(mat);
value.set(mat.data());
}
}
void BoundingVolume::read(NIFStream* nif) void BoundingVolume::read(NIFStream* nif)
{ {
nif->read(mType); nif->read(mType);
@ -200,12 +210,13 @@ namespace Nif
{ {
if (nif->getVersion() < NIFStream::generateVersion(10, 0, 1, 0)) if (nif->getVersion() < NIFStream::generateVersion(10, 0, 1, 0))
return; return;
std::uint32_t numNames = 0;
if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5)) if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
mNames.resize(nif->get<uint32_t>()); numNames = nif->get<uint32_t>();
else if (nif->getVersion() <= NIFStream::generateVersion(20, 1, 0, 3)) else if (nif->getVersion() <= NIFStream::generateVersion(20, 1, 0, 3))
mNames.resize(nif->get<bool>()); numNames = nif->get<bool>();
nif->readVector(mNames, mNames.size()); nif->readVector(mNames, numNames);
nif->readVector(mExtra, mNames.size()); nif->readVector(mExtra, numNames);
if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5)) if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
nif->read(mActive); nif->read(mActive);
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS) if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
@ -371,9 +382,7 @@ namespace Nif
{ {
NiTriShape::read(nif); NiTriShape::read(nif);
mSegments.resize(nif->get<uint32_t>()); nif->readVectorOfRecords<uint32_t>(mSegments);
for (SegmentData& segment : mSegments)
segment.read(nif);
} }
void BSLODTriShape::read(NIFStream* nif) void BSLODTriShape::read(NIFStream* nif)
@ -540,17 +549,19 @@ namespace Nif
mAlphaProperty.read(nif); mAlphaProperty.read(nif);
mVertDesc.read(nif); mVertDesc.read(nif);
size_t numTriangleIndices;
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO4) if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO4)
mTriangles.resize(nif->get<uint32_t>() * 3); numTriangleIndices = nif->get<uint32_t>() * 3;
else else
mTriangles.resize(nif->get<uint16_t>() * 3); numTriangleIndices = nif->get<uint16_t>() * 3;
mVertData.resize(nif->get<uint16_t>()); nif->read(mNumVertices);
mVertData.reserve(mNumVertices);
nif->read(mDataSize); nif->read(mDataSize);
if (mDataSize > 0) if (mDataSize > 0)
{ {
for (auto& vertex : mVertData) for (uint16_t i = 0; i < mNumVertices; ++i)
vertex.read(nif, mVertDesc.mFlags); mVertData.emplace_back().read(nif, mVertDesc.mFlags);
nif->readVector(mTriangles, mTriangles.size()); nif->readVector(mTriangles, numTriangleIndices);
} }
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE) if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE)
@ -558,9 +569,9 @@ namespace Nif
nif->read(mParticleDataSize); nif->read(mParticleDataSize);
if (mParticleDataSize > 0) if (mParticleDataSize > 0)
{ {
nif->readVector(mParticleVerts, mVertData.size() * 3); nif->readVector(mParticleVerts, mNumVertices * 3);
nif->readVector(mParticleNormals, mVertData.size() * 3); nif->readVector(mParticleNormals, mNumVertices * 3);
nif->readVector(mParticleTriangles, mTriangles.size()); nif->readVector(mParticleTriangles, numTriangleIndices);
} }
} }
} }
@ -582,8 +593,8 @@ namespace Nif
nif->read(mDynamicDataSize); nif->read(mDynamicDataSize);
// nifly style. // nifly style.
// Consider complaining if mDynamicDataSize * 16 != mVertData.size()? // Consider complaining if mDynamicDataSize * 16 != mNumVertices?
nif->readVector(mDynamicData, mVertData.size()); nif->readVector(mDynamicData, mNumVertices);
} }
void BSMeshLODTriShape::read(NIFStream* nif) void BSMeshLODTriShape::read(NIFStream* nif)
@ -606,9 +617,7 @@ namespace Nif
nif->read(mStartIndex); nif->read(mStartIndex);
nif->read(mNumPrimitives); nif->read(mNumPrimitives);
nif->read(mParentArrayIndex); nif->read(mParentArrayIndex);
mSubSegments.resize(nif->get<uint32_t>()); nif->readVectorOfRecords<uint32_t>(mSubSegments);
for (SubSegment& subsegment : mSubSegments)
subsegment.read(nif);
} }
void BSSubIndexTriShape::SubSegmentDataRecord::read(NIFStream* nif) void BSSubIndexTriShape::SubSegmentDataRecord::read(NIFStream* nif)
@ -622,22 +631,19 @@ namespace Nif
{ {
uint32_t numArrayIndices; uint32_t numArrayIndices;
nif->read(numArrayIndices); nif->read(numArrayIndices);
mDataRecords.resize(nif->get<uint32_t>()); const uint32_t numRecords = nif->get<uint32_t>();
nif->readVector(mArrayIndices, numArrayIndices); nif->readVector(mArrayIndices, numArrayIndices);
for (SubSegmentDataRecord& dataRecord : mDataRecords) nif->readVectorOfRecords(numRecords, mDataRecords);
dataRecord.read(nif);
mSSFFile = nif->getSizedString(nif->get<uint16_t>()); mSSFFile = nif->getSizedString(nif->get<uint16_t>());
} }
void BSSubIndexTriShape::Segmentation::read(NIFStream* nif) void BSSubIndexTriShape::Segmentation::read(NIFStream* nif)
{ {
nif->read(mNumPrimitives); nif->read(mNumPrimitives);
mSegments.resize(nif->get<uint32_t>()); const uint32_t numSegments = nif->get<uint32_t>();
nif->read(mNumTotalSegments); nif->read(mNumTotalSegments);
for (Segment& segment : mSegments) nif->readVectorOfRecords(numSegments, mSegments);
segment.read(nif); if (numSegments < mNumTotalSegments)
if (mSegments.size() < mNumTotalSegments)
mSubSegmentData.read(nif); mSubSegmentData.read(nif);
} }
@ -646,11 +652,7 @@ namespace Nif
BSTriShape::read(nif); BSTriShape::read(nif);
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE) if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE)
{ nif->readVectorOfRecords<uint32_t>(mSegments);
mSegments.resize(nif->get<uint32_t>());
for (BSSegmentedTriShape::SegmentData& segment : mSegments)
segment.read(nif);
}
else if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO4 && mDataSize > 0) else if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO4 && mDataSize > 0)
mSegmentation.read(nif); mSegmentation.read(nif);
} }
@ -752,30 +754,23 @@ namespace Nif
{ {
mResourceID.read(nif); mResourceID.read(nif);
nif->skip(12 * nif->get<uint32_t>()); // Unknown data nif->skip(12 * nif->get<uint32_t>()); // Unknown data
mTransforms.resize(nif->get<uint32_t>()); nif->readVectorOfRecords<uint32_t>(readBSDistantObjectInstanceTransform, mTransforms);
for (osg::Matrixf& transform : mTransforms)
{
std::array<float, 16> mat;
nif->readArray(mat);
transform.set(mat.data());
}
} }
void BSShaderTextureArray::read(NIFStream* nif) void BSShaderTextureArray::read(NIFStream* nif)
{ {
nif->skip(1); // Unknown nif->skip(1); // Unknown
mTextureArrays.resize(nif->get<uint32_t>()); const uint32_t numArrays = nif->get<uint32_t>();
for (std::vector<std::string>& textureArray : mTextureArrays) mTextureArrays.reserve(numArrays);
nif->getSizedStrings(textureArray, nif->get<uint32_t>()); for (uint32_t i = 0; i < numArrays; ++i)
nif->getSizedStrings(mTextureArrays.emplace_back(), nif->get<uint32_t>());
} }
void BSDistantObjectInstancedNode::read(NIFStream* nif) void BSDistantObjectInstancedNode::read(NIFStream* nif)
{ {
BSMultiBoundNode::read(nif); BSMultiBoundNode::read(nif);
mInstances.resize(nif->get<uint32_t>()); nif->readVectorOfRecords<uint32_t>(mInstances);
for (BSDistantObjectInstance& instance : mInstances)
instance.read(nif);
for (BSShaderTextureArray& textureArray : mShaderTextureArrays) for (BSShaderTextureArray& textureArray : mShaderTextureArrays)
textureArray.read(nif); textureArray.read(nif);
} }

View file

@ -385,6 +385,7 @@ namespace Nif
NiAlphaPropertyPtr mAlphaProperty; NiAlphaPropertyPtr mAlphaProperty;
BSVertexDesc mVertDesc; BSVertexDesc mVertDesc;
uint32_t mDataSize; uint32_t mDataSize;
uint16_t mNumVertices;
std::vector<BSVertexData> mVertData; std::vector<BSVertexData> mVertData;
std::vector<unsigned short> mTriangles; std::vector<unsigned short> mTriangles;
uint32_t mParticleDataSize; uint32_t mParticleDataSize;