From c0b9823372e3da7e91d57c8c2029a957efa5a481 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sun, 13 Dec 2020 04:04:14 +0300 Subject: [PATCH] Read BSShaderProperty and handle NiGeometry properties --- components/nif/niffile.cpp | 1 + components/nif/node.hpp | 9 ++++++++- components/nif/property.cpp | 12 ++++++++++++ components/nif/property.hpp | 7 +++++++ components/nif/record.hpp | 3 ++- components/nif/recordptr.hpp | 4 ++++ components/nifosg/nifloader.cpp | 14 ++++++++++++++ 7 files changed, 48 insertions(+), 2 deletions(-) diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 8aa0b60350..665533c91b 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -132,6 +132,7 @@ static std::map makeFactory() factory["NiColorInterpolator"] = {&construct , RC_NiColorInterpolator }; factory["BSShaderTextureSet"] = {&construct , RC_BSShaderTextureSet }; factory["BSLODTriShape"] = {&construct , RC_BSLODTriShape }; + factory["BSShaderProperty"] = {&construct , RC_BSShaderProperty }; return factory; } diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 75041e187d..08f066e361 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -278,6 +278,8 @@ struct NiGeometry : Node NiGeometryDataPtr data; NiSkinInstancePtr skin; MaterialData material; + BSShaderPropertyPtr shaderprop; + NiAlphaPropertyPtr alphaprop; void read(NIFStream *nif) override { @@ -286,7 +288,10 @@ struct NiGeometry : Node skin.read(nif); material.read(nif); if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3) - nif->skip(8); + { + shaderprop.read(nif); + alphaprop.read(nif); + } } void post(NIFFile *nif) override @@ -294,6 +299,8 @@ struct NiGeometry : Node Node::post(nif); data.post(nif); skin.post(nif); + shaderprop.post(nif); + alphaprop.post(nif); if (recType != RC_NiParticles && !skin.empty()) nif->setUseSkinning(true); } diff --git a/components/nif/property.cpp b/components/nif/property.cpp index e6ae71c241..55113d7c88 100644 --- a/components/nif/property.cpp +++ b/components/nif/property.cpp @@ -99,6 +99,18 @@ void NiTexturingProperty::post(NIFFile *nif) shaderTextures[i].post(nif); } +void BSShaderProperty::read(NIFStream *nif) +{ + NiShadeProperty::read(nif); + if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3) + { + type = nif->getUInt(); + flags1 = nif->getUInt(); + flags2 = nif->getUInt(); + envMapIntensity = nif->getFloat(); + } +} + void NiFogProperty::read(NIFStream *nif) { Property::read(nif); diff --git a/components/nif/property.hpp b/components/nif/property.hpp index c821b7c37e..5bc0c52dba 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -118,6 +118,13 @@ struct NiShadeProperty : public Property } }; +struct BSShaderProperty : public NiShadeProperty +{ + unsigned int type{0u}, flags1{0u}, flags2{0u}; + float envMapIntensity{0.f}; + void read(NIFStream *nif) override; +}; + struct NiDitherProperty : public Property { unsigned short flags; diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 6834c554ee..efacd82462 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -121,7 +121,8 @@ enum RecordType RC_NiTransformInterpolator, RC_NiColorInterpolator, RC_BSShaderTextureSet, - RC_BSLODTriShape + RC_BSLODTriShape, + RC_BSShaderProperty }; /// Base class for all records diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index dd6e357084..4792895e2d 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -146,6 +146,8 @@ struct NiPoint3Interpolator; struct NiTransformInterpolator; struct BSShaderTextureSet; struct NiGeometryData; +struct BSShaderProperty; +class NiAlphaProperty; using NodePtr = RecordPtrT; using ExtraPtr = RecordPtrT; @@ -171,6 +173,8 @@ using NiPoint3InterpolatorPtr = RecordPtrT; using NiTransformInterpolatorPtr = RecordPtrT; using BSShaderTextureSetPtr = RecordPtrT; using NiGeometryDataPtr = RecordPtrT; +using BSShaderPropertyPtr = RecordPtrT; +using NiAlphaPropertyPtr = RecordPtrT; using NodeList = RecordListT; using PropertyList = RecordListT; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index c3f4e50cf8..5f68b12291 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -96,6 +96,15 @@ namespace } } } + + auto geometry = dynamic_cast(nifNode); + if (geometry) + { + if (!geometry->shaderprop.empty()) + out.emplace_back(geometry->shaderprop.getPtr()); + if (!geometry->alphaprop.empty()) + out.emplace_back(geometry->alphaprop.getPtr()); + } } // NodeCallback used to have a node always oriented towards the camera. The node can have translation and scale @@ -366,6 +375,11 @@ namespace NifOsg handleProperty(props[i].getPtr(), applyTo, composite, imageManager, boundTextures, animflags); } } + + auto geometry = dynamic_cast(nifNode); + // NiGeometry's NiAlphaProperty doesn't get handled here because it's a drawable property + if (geometry && !geometry->shaderprop.empty()) + handleProperty(geometry->shaderprop.getPtr(), applyTo, composite, imageManager, boundTextures, animflags); } void setupController(const Nif::Controller* ctrl, SceneUtil::Controller* toSetup, int animflags)