diff --git a/include/Geometry.hpp b/include/Geometry.hpp index e7e94ed..dbf184e 100644 --- a/include/Geometry.hpp +++ b/include/Geometry.hpp @@ -652,6 +652,20 @@ class BSGeometry : public NiCloneableStreamable { bool GetTriangles(std::vector& tris) const override; void SetTriangles(const std::vector& tris) override; + bool IsSkinned() const override { return !skinInstanceRef.IsEmpty(); } + + bool HasSkinInstance() const override { return !skinInstanceRef.IsEmpty(); } + NiBlockRef* SkinInstanceRef() override { return &skinInstanceRef; } + const NiBlockRef* SkinInstanceRef() const override { return &skinInstanceRef; } + + bool HasShaderProperty() const override { return !shaderPropertyRef.IsEmpty(); } + NiBlockRef* ShaderPropertyRef() override { return &shaderPropertyRef; } + const NiBlockRef* ShaderPropertyRef() const override { return &shaderPropertyRef; } + + bool HasAlphaProperty() const override { return !alphaPropertyRef.IsEmpty(); } + NiBlockRef* AlphaPropertyRef() override { return &alphaPropertyRef; } + const NiBlockRef* AlphaPropertyRef() const override { return &alphaPropertyRef; } + uint8_t MeshCount() { return (uint8_t) meshes.size(); } // Flag 0x200 (512) on BSGeometry controls whether mesh data is embedded inline diff --git a/src/NifFile.cpp b/src/NifFile.cpp index 59ecb0c..5959190 100644 --- a/src/NifFile.cpp +++ b/src/NifFile.cpp @@ -2445,13 +2445,24 @@ uint32_t NifFile::GetShapeBoneList(NiShape* shape, std::vector& out return 0; auto skinInst = hdr.GetBlock(shape->SkinInstanceRef()); - if (!skinInst) - return 0; + if (skinInst) { + for (auto& bone : skinInst->boneRefs) { + auto node = hdr.GetBlock(bone); + if (node) + outList.push_back(node->name.get()); + } + } - for (auto& bone : skinInst->boneRefs) { - auto node = hdr.GetBlock(bone); - if (node) - outList.push_back(node->name.get()); + // SF NIFs store bone names in SkinAttach extra data instead of NiNode refs + if (outList.empty()) { + for (auto& extraDataRef : shape->extraDataRefs) { + auto skinAttach = hdr.GetBlock(extraDataRef); + if (skinAttach) { + for (auto& bone : skinAttach->bones) + outList.push_back(bone.get()); + break; + } + } } return static_cast(outList.size());