mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 06:35:30 +00:00
Modernize NiParticlesData and NiSkinData
This commit is contained in:
parent
89774716fb
commit
6ac271d5c0
@ -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<bool>() || (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0))
|
||||
numRadii = 0;
|
||||
}
|
||||
nif->readVector(mRadii, numRadii);
|
||||
|
||||
nif->read(mActiveCount);
|
||||
|
||||
if (nif->get<bool>())
|
||||
nif->readVector(mSizes, mNumVertices);
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
||||
{
|
||||
if (nif->get<bool>())
|
||||
nif->readVector(mRotations, mNumVertices);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4))
|
||||
{
|
||||
if (nif->get<bool>())
|
||||
nif->readVector(mRotationAngles, mNumVertices);
|
||||
if (nif->get<bool>())
|
||||
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<osg::Vec3f>(), nif->get<float>());
|
||||
|
||||
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)
|
||||
|
@ -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<float> particleRadii, sizes, rotationAngles;
|
||||
std::vector<osg::Quat> rotations;
|
||||
std::vector<osg::Vec3f> rotationAxes;
|
||||
std::vector<float> mRadii;
|
||||
std::vector<float> mSizes;
|
||||
std::vector<osg::Quat> mRotations;
|
||||
std::vector<float> mRotationAngles;
|
||||
std::vector<osg::Vec3f> 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<unsigned short, float>;
|
||||
|
||||
struct BoneInfo
|
||||
{
|
||||
Transformation trafo;
|
||||
osg::Vec3f boundSphereCenter;
|
||||
float boundSphereRadius;
|
||||
std::vector<VertWeight> weights;
|
||||
Transformation mTransform;
|
||||
osg::BoundingSpheref mBoundSphere;
|
||||
std::vector<VertWeight> mWeights;
|
||||
};
|
||||
|
||||
Transformation trafo;
|
||||
std::vector<BoneInfo> bones;
|
||||
NiSkinPartitionPtr partitions;
|
||||
Transformation mTransform;
|
||||
std::vector<BoneInfo> mBones;
|
||||
NiSkinPartitionPtr mPartitions;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
|
@ -1133,14 +1133,14 @@ namespace NifOsg
|
||||
}
|
||||
|
||||
auto particledata = static_cast<const Nif::NiParticlesData*>(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<Nif::NiSkinData::VertWeight>& 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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user