@@ -17,6 +17,24 @@ namespace Nif
1717 stream.read (weight);
1818 }
1919
20+ void readNiTriShapeDataMatchGroup (NIFStream& stream, std::vector<unsigned short >& value)
21+ {
22+ stream.readVector (value, stream.get <uint16_t >());
23+ }
24+
25+ struct ReadNiGeometryDataUVSet
26+ {
27+ uint16_t mNumVertices ;
28+
29+ void operator ()(NIFStream& stream, std::vector<osg::Vec2f>& value) const
30+ {
31+ stream.readVector (value, mNumVertices );
32+ // Flip the texture coordinates to convert them to the OpenGL convention of bottom-left image origin
33+ for (osg::Vec2f& uv : value)
34+ uv.y () = 1 .f - uv.y ();
35+ }
36+ };
37+
2038 struct ReadNiSkinDataBoneInfo
2139 {
2240 bool mHasVertexWeights ;
@@ -46,6 +64,27 @@ namespace Nif
4664 stream.readVector (value.mVertices , mNumVerts );
4765 }
4866 };
67+
68+ struct ReadNiAdditionalGeometryDataDataBlock
69+ {
70+ bool mBSPacked ;
71+
72+ void operator ()(NIFStream& stream, NiAdditionalGeometryData::DataBlock& value) const
73+ {
74+ stream.read (value.mValid );
75+ if (!value.mValid )
76+ return ;
77+ stream.read (value.mBlockSize );
78+ stream.readVector (value.mBlockOffsets , stream.get <uint32_t >());
79+ stream.readVector (value.mDataSizes , stream.get <uint32_t >());
80+ stream.readVector (value.mData , value.mDataSizes .size () * value.mBlockSize );
81+ if (!mBSPacked )
82+ return ;
83+
84+ stream.read (value.mShaderIndex );
85+ stream.read (value.mTotalSize );
86+ }
87+ };
4988 }
5089
5190 void NiGeometryData::read (NIFStream* nif)
@@ -118,14 +157,8 @@ namespace Nif
118157
119158 if (hasData)
120159 {
121- mUVList .resize (numUVs);
122- for (std::vector<osg::Vec2f>& list : mUVList )
123- {
124- nif->readVector (list, mNumVertices );
125- // flip the texture coordinates to convert them to the OpenGL convention of bottom-left image origin
126- for (osg::Vec2f& uv : list)
127- uv.y () = 1 .f - uv.y ();
128- }
160+ const ReadNiGeometryDataUVSet readUVSet{ .mNumVertices = mNumVertices };
161+ nif->readVectorOfRecords (numUVs, readUVSet, mUVList );
129162 }
130163
131164 if (nif->getVersion () >= NIFStream::generateVersion (10 , 0 , 1 , 0 ))
@@ -152,9 +185,7 @@ namespace Nif
152185 if (nif->getVersion () > NIFFile::NIFVersion::VER_OB_OLD && !nif->get <bool >())
153186 numIndices = 0 ;
154187 nif->readVector (mTriangles , numIndices);
155- mMatchGroups .resize (nif->get <uint16_t >());
156- for (auto & group : mMatchGroups )
157- nif->readVector (group, nif->get <uint16_t >());
188+ nif->readVectorOfRecords <uint16_t >(readNiTriShapeDataMatchGroup, mMatchGroups );
158189 }
159190
160191 void NiTriStripsData::read (NIFStream* nif)
@@ -165,11 +196,12 @@ namespace Nif
165196 nif->read (numStrips);
166197 std::vector<uint16_t > lengths;
167198 nif->readVector (lengths, numStrips);
168- if (nif->getVersion () > NIFFile::NIFVersion::VER_OB_OLD && !nif->get <bool >())
169- numStrips = 0 ;
170- mStrips .resize (numStrips);
171- for (int i = 0 ; i < numStrips; i++)
172- nif->readVector (mStrips [i], lengths[i]);
199+ if (nif->getVersion () <= NIFFile::NIFVersion::VER_OB_OLD || nif->get <bool >())
200+ {
201+ mStrips .reserve (numStrips);
202+ for (size_t i = 0 ; i < numStrips; ++i)
203+ nif->readVector (mStrips .emplace_back (), lengths[i]);
204+ }
173205 }
174206
175207 void NiLinesData::read (NIFStream* nif)
@@ -403,33 +435,34 @@ namespace Nif
403435 mPartitions .post (nif);
404436 }
405437
438+ void BSSkinBoneData::BoneInfo::read (NIFStream* nif)
439+ {
440+ nif->read (mBoundSphere );
441+ nif->read (mTransform );
442+ }
443+
406444 void BSSkinBoneData::read (NIFStream* nif)
407445 {
408- mBones .resize (nif->get <uint32_t >());
409- for (BoneInfo& bone : mBones )
410- {
411- nif->read (bone.mBoundSphere );
412- nif->read (bone.mTransform );
413- }
446+ nif->readVectorOfRecords <uint32_t >(mBones );
414447 }
415448
416449 void NiSkinPartition::read (NIFStream* nif)
417450 {
418- mPartitions . resize ( nif->get <uint32_t >() );
451+ const uint32_t numPartitions = nif->get <uint32_t >();
419452
420453 if (nif->getBethVersion () == NIFFile::BethVersion::BETHVER_SSE)
421454 {
422455 nif->read (mDataSize );
423456 nif->read (mVertexSize );
424457 mVertexDesc .read (nif);
425458
426- mVertexData .resize (mDataSize / mVertexSize );
427- for (auto & vertexData : mVertexData )
428- vertexData.read (nif, mVertexDesc .mFlags );
459+ uint32_t numVertices = mDataSize / mVertexSize ;
460+ mVertexData .reserve (numVertices);
461+ for (uint32_t i = 0 ; i < numVertices; ++i)
462+ mVertexData .emplace_back ().read (nif, mVertexDesc .mFlags );
429463 }
430464
431- for (auto & partition : mPartitions )
432- partition.read (nif);
465+ nif->readVectorOfRecords (numPartitions, mPartitions );
433466 }
434467
435468 void NiSkinPartition::Partition::read (NIFStream* nif)
@@ -452,9 +485,9 @@ namespace Nif
452485 {
453486 if (numStrips)
454487 {
455- mStrips .resize (numStrips);
456- for (size_t i = 0 ; i < numStrips; i++ )
457- nif->readVector (mStrips [i] , stripLengths[i]);
488+ mStrips .reserve (numStrips);
489+ for (size_t i = 0 ; i < numStrips; ++i )
490+ nif->readVector (mStrips . emplace_back () , stripLengths[i]);
458491 }
459492 else
460493 nif->readVector (mTriangles , numTriangles * 3 );
@@ -524,17 +557,15 @@ namespace Nif
524557
525558 void NiPalette::read (NIFStream* nif)
526559 {
527- bool useAlpha = nif->get <uint8_t >() != 0 ;
528- uint32_t alphaMask = useAlpha ? 0 : 0xFF000000 ;
529-
530- uint32_t numEntries;
531- nif->read (numEntries);
532- // Fill the entire palette with black even if there isn't enough entries.
533- mColors .resize (numEntries > 256 ? numEntries : 256 );
560+ const bool useAlpha = nif->get <uint8_t >() != 0 ;
561+ const uint32_t alphaMask = useAlpha ? 0 : 0xFF000000 ;
562+ const uint32_t numEntries = nif->get <uint32_t >();
534563 for (uint32_t i = 0 ; i < numEntries; i++)
535564 {
536- nif->read (mColors [i]);
537- mColors [i] |= alphaMask;
565+ const uint32_t color = nif->get <uint32_t >();
566+ // Indices past 255 are always unused
567+ if (i < 256 )
568+ mColors [i] = color | alphaMask;
538569 }
539570 }
540571
@@ -566,12 +597,10 @@ namespace Nif
566597 void NiAdditionalGeometryData::read (NIFStream* nif)
567598 {
568599 nif->read (mNumVertices );
569- mBlockInfos .resize (nif->get <uint32_t >());
570- for (DataStream& info : mBlockInfos )
571- info.read (nif);
572- mBlocks .resize (nif->get <uint32_t >());
573- for (DataBlock& block : mBlocks )
574- block.read (nif, recType == RC_BSPackedAdditionalGeometryData);
600+ nif->readVectorOfRecords <uint32_t >(mBlockInfos );
601+ const ReadNiAdditionalGeometryDataDataBlock readDataBlock{ .mBSPacked
602+ = recType == RC_BSPackedAdditionalGeometryData };
603+ nif->readVectorOfRecords <uint32_t >(readDataBlock, mBlocks );
575604 }
576605
577606 void NiAdditionalGeometryData::DataStream::read (NIFStream* nif)
@@ -585,22 +614,6 @@ namespace Nif
585614 nif->read (mFlags );
586615 }
587616
588- void NiAdditionalGeometryData::DataBlock::read (NIFStream* nif, bool bsPacked)
589- {
590- nif->read (mValid );
591- if (!mValid )
592- return ;
593- nif->read (mBlockSize );
594- nif->readVector (mBlockOffsets , nif->get <uint32_t >());
595- nif->readVector (mDataSizes , nif->get <uint32_t >());
596- nif->readVector (mData , mDataSizes .size () * mBlockSize );
597- if (bsPacked)
598- {
599- nif->read (mShaderIndex );
600- nif->read (mTotalSize );
601- }
602- }
603-
604617 void BSMultiBound::read (NIFStream* nif)
605618 {
606619 mData .read (nif);
@@ -646,9 +659,7 @@ namespace Nif
646659
647660 void BSAnimNotes::read (NIFStream* nif)
648661 {
649- mList .resize (nif->get <uint16_t >());
650- for (auto & note : mList )
651- note.read (nif);
662+ nif->readVectorOfRecords <uint16_t >(mList );
652663 }
653664
654665 void BSAnimNotes::post (Reader& nif)
0 commit comments