diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 89559a9149..e92d4e74bc 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -280,6 +280,7 @@ namespace Nif { "BSLODTriShape", &construct }, { "BSMeshLODTriShape", &construct }, { "BSSegmentedTriShape", &construct }, + { "BSSubIndexTriShape", &construct }, // PARTICLES diff --git a/components/nif/node.cpp b/components/nif/node.cpp index 8f5443b28e..28cd2cdbfe 100644 --- a/components/nif/node.cpp +++ b/components/nif/node.cpp @@ -218,17 +218,20 @@ namespace Nif } } + void BSSegmentedTriShape::SegmentData::read(NIFStream* nif) + { + nif->read(mFlags); + nif->read(mStartIndex); + nif->read(mNumTriangles); + } + void BSSegmentedTriShape::read(NIFStream* nif) { NiTriShape::read(nif); mSegments.resize(nif->get()); for (SegmentData& segment : mSegments) - { - nif->read(segment.mFlags); - nif->read(segment.mStartIndex); - nif->read(segment.mNumTriangles); - } + segment.read(nif); } void BSLODTriShape::read(NIFStream* nif) @@ -447,6 +450,68 @@ namespace Nif nif->readArray(mLOD); } + void BSSubIndexTriShape::SubSegment::read(NIFStream* nif) + { + nif->read(mStartIndex); + nif->read(mNumPrimitives); + nif->read(mArrayIndex); + nif->skip(4); // Unknown + } + + void BSSubIndexTriShape::Segment::read(NIFStream* nif) + { + nif->read(mStartIndex); + nif->read(mNumPrimitives); + nif->read(mParentArrayIndex); + mSubSegments.resize(nif->get()); + for (SubSegment& subsegment : mSubSegments) + subsegment.read(nif); + } + + void BSSubIndexTriShape::SubSegmentDataRecord::read(NIFStream* nif) + { + nif->read(mUserSlotID); + nif->read(mMaterial); + nif->readVector(mExtraData, nif->get()); + } + + void BSSubIndexTriShape::SubSegmentData::read(NIFStream* nif) + { + uint32_t numArrayIndices; + nif->read(numArrayIndices); + mDataRecords.resize(nif->get()); + nif->readVector(mArrayIndices, numArrayIndices); + for (SubSegmentDataRecord& dataRecord : mDataRecords) + dataRecord.read(nif); + mSSFFile = nif->getSizedString(nif->get()); + } + + void BSSubIndexTriShape::Segmentation::read(NIFStream* nif) + { + nif->read(mNumPrimitives); + mSegments.resize(nif->get()); + nif->read(mNumTotalSegments); + for (Segment& segment : mSegments) + segment.read(nif); + + if (mSegments.size() < mNumTotalSegments) + mSubSegmentData.read(nif); + } + + void BSSubIndexTriShape::read(NIFStream* nif) + { + BSTriShape::read(nif); + + if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE) + { + mSegments.resize(nif->get()); + for (BSSegmentedTriShape::SegmentData& segment : mSegments) + segment.read(nif); + } + else if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO4 && mDataSize > 0) + mSegmentation.read(nif); + } + void BSVertexDesc::read(NIFStream* nif) { uint64_t data; diff --git a/components/nif/node.hpp b/components/nif/node.hpp index e873fc27dc..0aaad40ed4 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -164,6 +164,8 @@ namespace Nif uint8_t mFlags; uint32_t mStartIndex; uint32_t mNumTriangles; + + void read(NIFStream* nif); }; std::vector mSegments; @@ -396,6 +398,61 @@ namespace Nif void read(NIFStream* nif) override; }; + struct BSSubIndexTriShape : BSTriShape + { + struct SubSegment + { + uint32_t mStartIndex; + uint32_t mNumPrimitives; + uint32_t mArrayIndex; + + void read(NIFStream* nif); + }; + + struct Segment + { + uint32_t mStartIndex; + uint32_t mNumPrimitives; + uint32_t mParentArrayIndex; + std::vector mSubSegments; + + void read(NIFStream* nif); + }; + + struct SubSegmentDataRecord + { + uint32_t mUserSlotID; + uint32_t mMaterial; + std::vector mExtraData; + + void read(NIFStream* nif); + }; + + struct SubSegmentData + { + std::vector mArrayIndices; + std::vector mDataRecords; + std::string mSSFFile; + + void read(NIFStream* nif); + }; + + struct Segmentation + { + uint32_t mNumPrimitives; + uint32_t mNumTotalSegments; + std::vector mSegments; + SubSegmentData mSubSegmentData; + + void read(NIFStream* nif); + }; + + std::vector mSegments; // SSE + Segmentation mSegmentation; // FO4 + + void read(NIFStream* nif) override; + }; + struct BSValueNode : NiNode { enum Flags diff --git a/components/nif/record.hpp b/components/nif/record.hpp index a06dcfe2a9..07c3842113 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -132,6 +132,7 @@ namespace Nif RC_BSSkinBoneData, RC_BSSkinInstance, RC_BSSkyShaderProperty, + RC_BSSubIndexTriShape, RC_BSTriShape, RC_BSWArray, RC_BSWaterShaderProperty, diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index fdf51486ed..3b8c47e071 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -109,6 +109,7 @@ namespace case Nif::RC_BSTriShape: case Nif::RC_BSDynamicTriShape: case Nif::RC_BSMeshLODTriShape: + case Nif::RC_BSSubIndexTriShape: return true; } return false;