From 981e4821710c1e7ffc19d0a4eaaf0bb7ddb5b0a4 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Fri, 20 Oct 2023 16:29:45 +0300 Subject: [PATCH 1/3] Read BSSubIndexTriShape It's currently handled exactly like BSTriShape, which works ok enough for our purposes --- components/nif/niffile.cpp | 1 + components/nif/node.cpp | 75 ++++++++++++++++++++++++++++++--- components/nif/node.hpp | 57 +++++++++++++++++++++++++ components/nif/record.hpp | 1 + components/nifosg/nifloader.cpp | 1 + 5 files changed, 130 insertions(+), 5 deletions(-) diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 89559a91499..e92d4e74bc7 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 8f5443b28e8..28cd2cdbfe5 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 e873fc27dc2..0aaad40ed47 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 a06dcfe2a9e..07c38421132 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 fdf51486ed4..3b8c47e0711 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; From 23eb6289b3bb643005f422fc9eee0446e4e80089 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Fri, 20 Oct 2023 17:09:42 +0300 Subject: [PATCH 2/3] Read BSLightingShaderPropertyUShortController --- components/nif/niffile.cpp | 2 ++ components/nif/record.hpp | 1 + 2 files changed, 3 insertions(+) diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index e92d4e74bc7..202c551a05b 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -156,6 +156,8 @@ namespace Nif &construct }, { "BSLightingShaderPropertyFloatController", &construct }, + { "BSLightingShaderPropertyUShortController", + &construct }, { "bhkBlendController", &construct }, { "NiBSBoneLODController", &construct }, { "NiLightRadiusController", &construct }, diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 07c38421132..0679bd862aa 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -98,6 +98,7 @@ namespace Nif RC_BSLightingShaderProperty, RC_BSLightingShaderPropertyColorController, RC_BSLightingShaderPropertyFloatController, + RC_BSLightingShaderPropertyUShortController, RC_BSLODTriShape, RC_BSMaterialEmittanceMultController, RC_BSMeshLODTriShape, From 8ce9f7b9cf8b63498aa3cb95bdb6dd454e4b8340 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Fri, 20 Oct 2023 17:39:58 +0300 Subject: [PATCH 3/3] Read BSPackedCombinedSharedGeomDataExtra --- components/nif/extra.cpp | 46 +++++++++++++++++++++++++++++++++++++ components/nif/extra.hpp | 47 ++++++++++++++++++++++++++++++++++++++ components/nif/niffile.cpp | 2 ++ components/nif/record.hpp | 1 + 4 files changed, 96 insertions(+) diff --git a/components/nif/extra.cpp b/components/nif/extra.cpp index 1fc24e5f896..2d222f5a545 100644 --- a/components/nif/extra.cpp +++ b/components/nif/extra.cpp @@ -162,4 +162,50 @@ namespace Nif nif->getSizedStrings(mPointNames, nif->get()); } + void BSPackedGeomDataCombined::read(NIFStream* nif) + { + nif->read(mGrayscaleToPaletteScale); + nif->read(mTransform); + nif->read(mBoundingSphere); + } + + void BSPackedGeomObject::read(NIFStream* nif) + { + nif->read(mFileHash); + nif->read(mDataOffset); + } + + void BSPackedSharedGeomData::read(NIFStream* nif) + { + nif->read(mNumVertices); + nif->read(mLODLevels); + nif->read(mLOD0TriCount); + nif->read(mLOD0TriOffset); + nif->read(mLOD1TriCount); + nif->read(mLOD1TriOffset); + nif->read(mLOD2TriCount); + nif->read(mLOD2TriOffset); + mCombined.resize(nif->get()); + for (BSPackedGeomDataCombined& data : mCombined) + data.read(nif); + mVertexDesc.read(nif); + } + + void BSPackedCombinedSharedGeomDataExtra::read(NIFStream* nif) + { + NiExtraData::read(nif); + + mVertexDesc.read(nif); + nif->read(mNumVertices); + nif->read(mNumTriangles); + nif->read(mFlags1); + nif->read(mFlags2); + mObjects.resize(nif->get()); + for (BSPackedGeomObject& object : mObjects) + object.read(nif); + mObjectData.resize(mObjects.size()); + for (BSPackedSharedGeomData& objectData : mObjectData) + objectData.read(nif); + } + } diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index 0808e91b16f..1efa4ae7bb0 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -2,6 +2,7 @@ #define OPENMW_COMPONENTS_NIF_EXTRA_HPP #include "base.hpp" +#include "node.hpp" namespace Nif { @@ -199,5 +200,51 @@ namespace Nif }; }; + struct BSPackedGeomDataCombined + { + float mGrayscaleToPaletteScale; + NiTransform mTransform; + osg::BoundingSpheref mBoundingSphere; + + void read(NIFStream* nif); + }; + + struct BSPackedGeomObject + { + uint32_t mFileHash; + uint32_t mDataOffset; + + void read(NIFStream* nif); + }; + + struct BSPackedSharedGeomData + { + uint32_t mNumVertices; + uint32_t mLODLevels; + uint32_t mLOD0TriCount; + uint32_t mLOD0TriOffset; + uint32_t mLOD1TriCount; + uint32_t mLOD1TriOffset; + uint32_t mLOD2TriCount; + uint32_t mLOD2TriOffset; + std::vector mCombined; + BSVertexDesc mVertexDesc; + + void read(NIFStream* nif); + }; + + struct BSPackedCombinedSharedGeomDataExtra : NiExtraData + { + BSVertexDesc mVertexDesc; + uint32_t mNumVertices; + uint32_t mNumTriangles; + uint32_t mFlags1; + uint32_t mFlags2; + std::vector mObjects; + std::vector mObjectData; + + void read(NIFStream* nif) override; + }; + } #endif diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 202c551a05b..35a9eee787f 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -256,6 +256,8 @@ namespace Nif { "BSDistantObjectLargeRefExtraData", &construct }, { "BSEyeCenterExtraData", &construct }, + { "BSPackedCombinedSharedGeomDataExtra", + &construct }, { "BSPositionData", &construct }, { "BSWArray", &construct }, { "BSXFlags", &construct }, diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 0679bd862aa..79958b361dd 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -108,6 +108,7 @@ namespace Nif RC_BSMultiBoundSphere, RC_BSNiAlphaPropertyTestRefController, RC_BSPackedAdditionalGeometryData, + RC_BSPackedCombinedSharedGeomDataExtra, RC_BSParentVelocityModifier, RC_BSPositionData, RC_BSProceduralLightningController,