From 8efbdeaa57f43038167b4ff0d3dd375ddc35bdfd Mon Sep 17 00:00:00 2001 From: capostrophic Date: Thu, 8 Aug 2019 13:11:24 +0300 Subject: [PATCH] Load NiTriStrips/NiTriStripsData (don't do anything yet) --- components/nif/data.cpp | 19 ++++++++++++++++ components/nif/data.hpp | 9 ++++++++ components/nif/niffile.cpp | 2 ++ components/nif/node.hpp | 23 +++++++++++++++++++ components/nif/record.hpp | 2 ++ components/nif/recordptr.hpp | 2 ++ components/nifbullet/bulletnifloader.cpp | 11 ++++++++++ components/nifbullet/bulletnifloader.hpp | 2 ++ components/nifosg/nifloader.cpp | 28 +++++++++++++++++++++++- 9 files changed, 97 insertions(+), 1 deletion(-) diff --git a/components/nif/data.cpp b/components/nif/data.cpp index 086021930..485a2ddf8 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -90,6 +90,25 @@ void NiTriShapeData::read(NIFStream *nif) } } +void NiTriStripsData::read(NIFStream *nif) +{ + ShapeData::read(nif); + + // Every strip with n points defines n-2 triangles, so this should be unnecessary. + /*int tris =*/ nif->getUShort(); + + // Number of triangle strips + int numStrips = nif->getUShort(); + // Number of points in each strip + int lengths = nif->getUShort(); + for (int i = 0; i < numStrips; i++) + { + std::vector strip; + nif->getUShorts(strip, lengths); + strips.emplace_back(strip); + } +} + void NiAutoNormalParticlesData::read(NIFStream *nif) { ShapeData::read(nif); diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 6b7aa579b..fb1199cff 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -53,6 +53,15 @@ public: void read(NIFStream *nif); }; +class NiTriStripsData : public ShapeData +{ +public: + // Triangle strips, series of vertex indices. + std::vector> strips; + + void read(NIFStream *nif); +}; + class NiAutoNormalParticlesData : public ShapeData { public: diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 6675fef08..4b3760ba2 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -54,6 +54,7 @@ static std::map makeFactory() newFactory.insert(makeEntry("NiBSAnimationNode", &construct , RC_NiBSAnimationNode )); newFactory.insert(makeEntry("NiBillboardNode", &construct , RC_NiBillboardNode )); newFactory.insert(makeEntry("NiTriShape", &construct , RC_NiTriShape )); + newFactory.insert(makeEntry("NiTriStrips", &construct , RC_NiTriStrips )); newFactory.insert(makeEntry("NiRotatingParticles", &construct , RC_NiRotatingParticles )); newFactory.insert(makeEntry("NiAutoNormalParticles", &construct , RC_NiAutoNormalParticles )); newFactory.insert(makeEntry("NiCamera", &construct , RC_NiCamera )); @@ -96,6 +97,7 @@ static std::map makeFactory() newFactory.insert(makeEntry("NiParticleRotation", &construct , RC_NiParticleRotation )); newFactory.insert(makeEntry("NiFloatData", &construct , RC_NiFloatData )); newFactory.insert(makeEntry("NiTriShapeData", &construct , RC_NiTriShapeData )); + newFactory.insert(makeEntry("NiTriStripsData", &construct , RC_NiTriStripsData )); newFactory.insert(makeEntry("NiVisData", &construct , RC_NiVisData )); newFactory.insert(makeEntry("NiColorData", &construct , RC_NiColorData )); newFactory.insert(makeEntry("NiPixelData", &construct , RC_NiPixelData )); diff --git a/components/nif/node.hpp b/components/nif/node.hpp index cc1871d83..5e5f445cf 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -156,6 +156,29 @@ struct NiTriShape : Node } }; +struct NiTriStrips : Node +{ + NiTriStripsDataPtr data; + NiSkinInstancePtr skin; + + void read(NIFStream *nif) + { + Node::read(nif); + data.read(nif); + skin.read(nif); + } + + void post(NIFFile *nif) + { + Node::post(nif); + data.post(nif); + skin.post(nif); + if (!skin.empty()) + nif->setUseSkinning(true); + } +}; + + struct NiCamera : Node { struct Camera diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 4a044ac47..909c268bb 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -41,6 +41,7 @@ enum RecordType RC_NiBillboardNode, RC_AvoidNode, RC_NiTriShape, + RC_NiTriStrips, RC_NiRotatingParticles, RC_NiAutoNormalParticles, RC_NiBSParticleNode, @@ -80,6 +81,7 @@ enum RecordType RC_NiParticleRotation, RC_NiFloatData, RC_NiTriShapeData, + RC_NiTriStripsData, RC_NiVisData, RC_NiColorData, RC_NiPixelData, diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index e8aa8cb5b..977973517 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -135,6 +135,7 @@ class NiPixelData; class NiColorData; struct NiKeyframeData; class NiTriShapeData; +class NiTriStripsData; class NiSkinInstance; class NiSourceTexture; class NiRotatingParticlesData; @@ -154,6 +155,7 @@ typedef RecordPtrT NiFloatDataPtr; typedef RecordPtrT NiColorDataPtr; typedef RecordPtrT NiKeyframeDataPtr; typedef RecordPtrT NiTriShapeDataPtr; +typedef RecordPtrT NiTriStripsDataPtr; typedef RecordPtrT NiSkinInstancePtr; typedef RecordPtrT NiSourceTexturePtr; typedef RecordPtrT NiRotatingParticlesDataPtr; diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 8f98174ab..e35968d09 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -248,6 +248,10 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *n { handleNiTriShape(static_cast(node), flags, getWorldTransform(node), isAnimated, avoid); } + if(!node->hasBounds && node->recType == Nif::RC_NiTriStrips) + { + handleNiTriStrips(static_cast(node), flags, getWorldTransform(node), isAnimated, avoid); + } } // For NiNodes, loop through children @@ -330,4 +334,11 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, } } + +void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags, const osg::Matrixf &transform, + bool isAnimated, bool avoid) +{ + // do nothing for now +} + } // namespace NifBullet diff --git a/components/nifbullet/bulletnifloader.hpp b/components/nifbullet/bulletnifloader.hpp index de7e6bdcd..afc8772cd 100644 --- a/components/nifbullet/bulletnifloader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -26,6 +26,7 @@ namespace Nif class Node; struct Transformation; struct NiTriShape; + struct NiTriStrips; } namespace NifBullet @@ -59,6 +60,7 @@ private: bool hasAutoGeneratedCollision(const Nif::Node *rootNode); void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf& transform, bool isAnimated, bool avoid); + void handleNiTriStrips(const Nif::NiTriStrips *shape, int flags, const osg::Matrixf& transform, bool isAnimated, bool avoid); std::unique_ptr mCompoundShape; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 69840117d..576aa5d18 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -452,6 +452,7 @@ namespace NifOsg break; } case Nif::RC_NiTriShape: + case Nif::RC_NiTriStrips: case Nif::RC_NiAutoNormalParticles: case Nif::RC_NiRotatingParticles: // Leaf nodes in the NIF hierarchy, so won't be able to dynamically attach children. @@ -580,6 +581,11 @@ namespace NifOsg node->setDataVariance(osg::Object::DYNAMIC); } + if (nifNode->recType == Nif::RC_NiTriStrips && isAnimated) // the same thing for animated NiTriStrips + { + node->setDataVariance(osg::Object::DYNAMIC); + } + osg::ref_ptr composite = new SceneUtil::CompositeStateSetUpdater; applyNodeProperties(nifNode, node, composite, imageManager, boundTextures, animflags); @@ -603,6 +609,25 @@ namespace NifOsg handleMeshControllers(nifNode, node, composite, boundTextures, animflags); } } + if (nifNode->recType == Nif::RC_NiTriStrips && !skipMeshes) + { + const Nif::NiTriStrips* triStrips = static_cast(nifNode); + const std::string nodeName = Misc::StringUtils::lowerCase(triStrips->name); + static const std::string markerName = "tri editormarker"; + static const std::string shadowName = "shadow"; + static const std::string shadowName2 = "tri shadow"; + const bool isMarker = hasMarkers && !nodeName.compare(0, markerName.size(), markerName); + if (!isMarker && nodeName.compare(0, shadowName.size(), shadowName) && nodeName.compare(0, shadowName2.size(), shadowName2)) + { + if (triStrips->skin.empty()) {} + /*handleTriShape(triShape, node, composite, boundTextures, animflags);*/ + else {} + /*handleSkinnedTriShape(triShape, node, composite, boundTextures, animflags);*/ + + if (!nifNode->controller.empty()) {} + /*handleMeshControllers(nifNode, node, composite, boundTextures, animflags);*/ + } + } if(nifNode->recType == Nif::RC_NiAutoNormalParticles || nifNode->recType == Nif::RC_NiRotatingParticles) handleParticleSystem(nifNode, node, composite, animflags, rootNode); @@ -612,7 +637,8 @@ namespace NifOsg // Note: NiTriShapes are not allowed to have KeyframeControllers (the vanilla engine just crashes when there is one). // We can take advantage of this constraint for optimizations later. - if (nifNode->recType != Nif::RC_NiTriShape && !nifNode->controller.empty() && node->getDataVariance() == osg::Object::DYNAMIC) + if (nifNode->recType != Nif::RC_NiTriShape && nifNode->recType != Nif::RC_NiTriStrips + && !nifNode->controller.empty() && node->getDataVariance() == osg::Object::DYNAMIC) handleNodeControllers(nifNode, static_cast(node.get()), animflags); const Nif::NiNode *ninode = dynamic_cast(nifNode);