diff --git a/components/nif/extra.cpp b/components/nif/extra.cpp index 1fc24e5f89..2d222f5a54 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 0808e91b16..1efa4ae7bb 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 89559a9149..35a9eee787 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 }, @@ -254,6 +256,8 @@ namespace Nif { "BSDistantObjectLargeRefExtraData", &construct }, { "BSEyeCenterExtraData", &construct }, + { "BSPackedCombinedSharedGeomDataExtra", + &construct }, { "BSPositionData", &construct }, { "BSWArray", &construct }, { "BSXFlags", &construct }, @@ -280,6 +284,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..79958b361d 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, @@ -107,6 +108,7 @@ namespace Nif RC_BSMultiBoundSphere, RC_BSNiAlphaPropertyTestRefController, RC_BSPackedAdditionalGeometryData, + RC_BSPackedCombinedSharedGeomDataExtra, RC_BSParentVelocityModifier, RC_BSPositionData, RC_BSProceduralLightningController, @@ -132,6 +134,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;