diff --git a/components/nif/data.cpp b/components/nif/data.cpp index 7522543a58..16f5822bf0 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -165,26 +165,33 @@ namespace Nif // Should always match the number of vertices if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW) - numParticles = nif->getUShort(); + nif->read(mNumParticles); - if (nif->getVersion() <= NIFStream::generateVersion(10, 0, 1, 0)) - std::fill(particleRadii.begin(), particleRadii.end(), nif->getFloat()); - else if (nif->getBoolean()) - nif->readVector(particleRadii, mNumVertices); - activeCount = nif->getUShort(); - - // Particle sizes - if (nif->getBoolean()) - nif->readVector(sizes, mNumVertices); - - if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0) && nif->getBoolean()) - nif->readVector(rotations, mNumVertices); - if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4)) + bool numRadii = 1; + if (nif->getVersion() > NIFStream::generateVersion(10, 0, 1, 0)) { - if (nif->getBoolean()) - nif->readVector(rotationAngles, mNumVertices); - if (nif->getBoolean()) - nif->readVector(rotationAxes, mNumVertices); + numRadii = mNumVertices; + if (!nif->get() || (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0)) + numRadii = 0; + } + nif->readVector(mRadii, numRadii); + + nif->read(mActiveCount); + + if (nif->get()) + nif->readVector(mSizes, mNumVertices); + + if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0)) + { + if (nif->get()) + nif->readVector(mRotations, mNumVertices); + if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4)) + { + if (nif->get()) + nif->readVector(mRotationAngles, mNumVertices); + if (nif->get()) + nif->readVector(mRotationAxes, mNumVertices); + } } } @@ -198,7 +205,7 @@ namespace Nif bool hasRotations; nif->read(hasRotations); if (hasRotations) - nif->readVector(rotations, mNumVertices); + nif->readVector(mRotations, mNumVertices); } void NiPosData::read(NIFStream* nif) @@ -319,7 +326,7 @@ namespace Nif if (mData.empty() || mRoot.empty()) throw Nif::Exception("NiSkinInstance missing root or data", nif.getFilename()); - if (mBones.size() != mData->bones.size()) + if (mBones.size() != mData->mBones.size()) throw Nif::Exception("Mismatch in NiSkinData bone count", nif.getFilename()); for (auto& bone : mBones) @@ -344,45 +351,48 @@ namespace Nif void NiSkinData::read(NIFStream* nif) { - trafo.rotation = nif->getMatrix3(); - trafo.pos = nif->getVector3(); - trafo.scale = nif->getFloat(); - - int boneNum = nif->getInt(); - if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW - && nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 0)) - partitions.read(nif); + nif->read(mTransform.rotation); + nif->read(mTransform.pos); + nif->read(mTransform.scale); + uint32_t numBones; + nif->read(numBones); bool hasVertexWeights = true; - if (nif->getVersion() > NIFStream::generateVersion(4, 2, 1, 0)) - hasVertexWeights = nif->getBoolean(); - - bones.resize(boneNum); - for (BoneInfo& bi : bones) + if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW) { - bi.trafo.rotation = nif->getMatrix3(); - bi.trafo.pos = nif->getVector3(); - bi.trafo.scale = nif->getFloat(); - bi.boundSphereCenter = nif->getVector3(); - bi.boundSphereRadius = nif->getFloat(); + if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 0)) + mPartitions.read(nif); - size_t numVertices = nif->getUShort(); + if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 1, 0)) + nif->read(hasVertexWeights); + } + + mBones.resize(numBones); + for (BoneInfo& bi : mBones) + { + nif->read(bi.mTransform.rotation); + nif->read(bi.mTransform.pos); + nif->read(bi.mTransform.scale); + bi.mBoundSphere = osg::BoundingSpheref(nif->get(), nif->get()); + + uint16_t numVertices; + nif->read(numVertices); if (!hasVertexWeights) continue; - bi.weights.resize(numVertices); - for (size_t j = 0; j < bi.weights.size(); j++) + bi.mWeights.resize(numVertices); + for (auto& [vertex, weight] : bi.mWeights) { - bi.weights[j].vertex = nif->getUShort(); - bi.weights[j].weight = nif->getFloat(); + nif->read(vertex); + nif->read(weight); } } } void NiSkinData::post(Reader& nif) { - partitions.post(nif); + mPartitions.post(nif); } void NiSkinPartition::read(NIFStream* nif) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 6791265b45..c55dd7ffd8 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -96,13 +96,14 @@ namespace Nif struct NiParticlesData : public NiGeometryData { - int numParticles{ 0 }; + uint16_t mNumParticles{ 0 }; + uint16_t mActiveCount; - int activeCount{ 0 }; - - std::vector particleRadii, sizes, rotationAngles; - std::vector rotations; - std::vector rotationAxes; + std::vector mRadii; + std::vector mSizes; + std::vector mRotations; + std::vector mRotationAngles; + std::vector mRotationAxes; void read(NIFStream* nif) override; }; @@ -267,23 +268,18 @@ namespace Nif struct NiSkinData : public Record { - struct VertWeight - { - unsigned short vertex; - float weight; - }; + using VertWeight = std::pair; struct BoneInfo { - Transformation trafo; - osg::Vec3f boundSphereCenter; - float boundSphereRadius; - std::vector weights; + Transformation mTransform; + osg::BoundingSpheref mBoundSphere; + std::vector mWeights; }; - Transformation trafo; - std::vector bones; - NiSkinPartitionPtr partitions; + Transformation mTransform; + std::vector mBones; + NiSkinPartitionPtr mPartitions; void read(NIFStream* nif) override; void post(Reader& nif) override; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index e56583e493..c748c1a6ae 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1133,14 +1133,14 @@ namespace NifOsg } auto particledata = static_cast(particleNode->data.getPtr()); - partsys->setQuota(particledata->numParticles); + partsys->setQuota(particledata->mNumParticles); osg::BoundingBox box; int i = 0; for (const auto& particle : partctrl->particles) { - if (i++ >= particledata->activeCount) + if (i++ >= particledata->mActiveCount) break; if (particle.lifespan <= 0) @@ -1165,8 +1165,8 @@ namespace NifOsg created->setAlphaRange(osgParticle::rangef(1.f, 1.f)); float size = partctrl->size; - if (particle.vertex < particledata->sizes.size()) - size *= particledata->sizes[particle.vertex]; + if (particle.vertex < particledata->mSizes.size()) + size *= particledata->mSizes[particle.vertex]; created->setSizeRange(osgParticle::rangef(size, size)); box.expandBy(osg::BoundingSphere(position, size)); @@ -1394,8 +1394,8 @@ namespace NifOsg if (!skin->mData.empty()) { data = skin->mData.getPtr(); - if (!data->partitions.empty()) - partitions = data->partitions.getPtr(); + if (!data->mPartitions.empty()) + partitions = data->mPartitions.getPtr(); } if (!partitions && !skin->mPartitions.empty()) partitions = skin->mPartitions.getPtr(); @@ -1556,14 +1556,9 @@ namespace NifOsg std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->name); SceneUtil::RigGeometry::BoneInfluence influence; - const std::vector& weights = data->bones[i].weights; - for (size_t j = 0; j < weights.size(); j++) - { - influence.mWeights.emplace_back(weights[j].vertex, weights[j].weight); - } - influence.mInvBindMatrix = data->bones[i].trafo.toMatrix(); - influence.mBoundSphere - = osg::BoundingSpheref(data->bones[i].boundSphereCenter, data->bones[i].boundSphereRadius); + influence.mWeights = data->mBones[i].mWeights; + influence.mInvBindMatrix = data->mBones[i].mTransform.toMatrix(); + influence.mBoundSphere = data->mBones[i].mBoundSphere; map->mData.emplace_back(boneName, influence); }