mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 22:15:37 +00:00
Modernize NiParticlesData and NiSkinData
This commit is contained in:
parent
89774716fb
commit
6ac271d5c0
3 changed files with 77 additions and 76 deletions
|
@ -165,26 +165,33 @@ namespace Nif
|
||||||
|
|
||||||
// Should always match the number of vertices
|
// Should always match the number of vertices
|
||||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)
|
||||||
numParticles = nif->getUShort();
|
nif->read(mNumParticles);
|
||||||
|
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(10, 0, 1, 0))
|
bool numRadii = 1;
|
||||||
std::fill(particleRadii.begin(), particleRadii.end(), nif->getFloat());
|
if (nif->getVersion() > NIFStream::generateVersion(10, 0, 1, 0))
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
if (nif->getBoolean())
|
numRadii = mNumVertices;
|
||||||
nif->readVector(rotationAngles, mNumVertices);
|
if (!nif->get<bool>() || (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0))
|
||||||
if (nif->getBoolean())
|
numRadii = 0;
|
||||||
nif->readVector(rotationAxes, mNumVertices);
|
}
|
||||||
|
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;
|
bool hasRotations;
|
||||||
nif->read(hasRotations);
|
nif->read(hasRotations);
|
||||||
if (hasRotations)
|
if (hasRotations)
|
||||||
nif->readVector(rotations, mNumVertices);
|
nif->readVector(mRotations, mNumVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiPosData::read(NIFStream* nif)
|
void NiPosData::read(NIFStream* nif)
|
||||||
|
@ -319,7 +326,7 @@ namespace Nif
|
||||||
if (mData.empty() || mRoot.empty())
|
if (mData.empty() || mRoot.empty())
|
||||||
throw Nif::Exception("NiSkinInstance missing root or data", nif.getFilename());
|
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());
|
throw Nif::Exception("Mismatch in NiSkinData bone count", nif.getFilename());
|
||||||
|
|
||||||
for (auto& bone : mBones)
|
for (auto& bone : mBones)
|
||||||
|
@ -344,45 +351,48 @@ namespace Nif
|
||||||
|
|
||||||
void NiSkinData::read(NIFStream* nif)
|
void NiSkinData::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
trafo.rotation = nif->getMatrix3();
|
nif->read(mTransform.rotation);
|
||||||
trafo.pos = nif->getVector3();
|
nif->read(mTransform.pos);
|
||||||
trafo.scale = nif->getFloat();
|
nif->read(mTransform.scale);
|
||||||
|
|
||||||
int boneNum = nif->getInt();
|
|
||||||
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW
|
|
||||||
&& nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 0))
|
|
||||||
partitions.read(nif);
|
|
||||||
|
|
||||||
|
uint32_t numBones;
|
||||||
|
nif->read(numBones);
|
||||||
bool hasVertexWeights = true;
|
bool hasVertexWeights = true;
|
||||||
if (nif->getVersion() > NIFStream::generateVersion(4, 2, 1, 0))
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
|
||||||
hasVertexWeights = nif->getBoolean();
|
|
||||||
|
|
||||||
bones.resize(boneNum);
|
|
||||||
for (BoneInfo& bi : bones)
|
|
||||||
{
|
{
|
||||||
bi.trafo.rotation = nif->getMatrix3();
|
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 0))
|
||||||
bi.trafo.pos = nif->getVector3();
|
mPartitions.read(nif);
|
||||||
bi.trafo.scale = nif->getFloat();
|
|
||||||
bi.boundSphereCenter = nif->getVector3();
|
|
||||||
bi.boundSphereRadius = nif->getFloat();
|
|
||||||
|
|
||||||
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)
|
if (!hasVertexWeights)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bi.weights.resize(numVertices);
|
bi.mWeights.resize(numVertices);
|
||||||
for (size_t j = 0; j < bi.weights.size(); j++)
|
for (auto& [vertex, weight] : bi.mWeights)
|
||||||
{
|
{
|
||||||
bi.weights[j].vertex = nif->getUShort();
|
nif->read(vertex);
|
||||||
bi.weights[j].weight = nif->getFloat();
|
nif->read(weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiSkinData::post(Reader& nif)
|
void NiSkinData::post(Reader& nif)
|
||||||
{
|
{
|
||||||
partitions.post(nif);
|
mPartitions.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiSkinPartition::read(NIFStream* nif)
|
void NiSkinPartition::read(NIFStream* nif)
|
||||||
|
|
|
@ -96,13 +96,14 @@ namespace Nif
|
||||||
|
|
||||||
struct NiParticlesData : public NiGeometryData
|
struct NiParticlesData : public NiGeometryData
|
||||||
{
|
{
|
||||||
int numParticles{ 0 };
|
uint16_t mNumParticles{ 0 };
|
||||||
|
uint16_t mActiveCount;
|
||||||
|
|
||||||
int activeCount{ 0 };
|
std::vector<float> mRadii;
|
||||||
|
std::vector<float> mSizes;
|
||||||
std::vector<float> particleRadii, sizes, rotationAngles;
|
std::vector<osg::Quat> mRotations;
|
||||||
std::vector<osg::Quat> rotations;
|
std::vector<float> mRotationAngles;
|
||||||
std::vector<osg::Vec3f> rotationAxes;
|
std::vector<osg::Vec3f> mRotationAxes;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
@ -267,23 +268,18 @@ namespace Nif
|
||||||
|
|
||||||
struct NiSkinData : public Record
|
struct NiSkinData : public Record
|
||||||
{
|
{
|
||||||
struct VertWeight
|
using VertWeight = std::pair<unsigned short, float>;
|
||||||
{
|
|
||||||
unsigned short vertex;
|
|
||||||
float weight;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BoneInfo
|
struct BoneInfo
|
||||||
{
|
{
|
||||||
Transformation trafo;
|
Transformation mTransform;
|
||||||
osg::Vec3f boundSphereCenter;
|
osg::BoundingSpheref mBoundSphere;
|
||||||
float boundSphereRadius;
|
std::vector<VertWeight> mWeights;
|
||||||
std::vector<VertWeight> weights;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Transformation trafo;
|
Transformation mTransform;
|
||||||
std::vector<BoneInfo> bones;
|
std::vector<BoneInfo> mBones;
|
||||||
NiSkinPartitionPtr partitions;
|
NiSkinPartitionPtr mPartitions;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
void post(Reader& nif) override;
|
void post(Reader& nif) override;
|
||||||
|
|
|
@ -1133,14 +1133,14 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
|
|
||||||
auto particledata = static_cast<const Nif::NiParticlesData*>(particleNode->data.getPtr());
|
auto particledata = static_cast<const Nif::NiParticlesData*>(particleNode->data.getPtr());
|
||||||
partsys->setQuota(particledata->numParticles);
|
partsys->setQuota(particledata->mNumParticles);
|
||||||
|
|
||||||
osg::BoundingBox box;
|
osg::BoundingBox box;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto& particle : partctrl->particles)
|
for (const auto& particle : partctrl->particles)
|
||||||
{
|
{
|
||||||
if (i++ >= particledata->activeCount)
|
if (i++ >= particledata->mActiveCount)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (particle.lifespan <= 0)
|
if (particle.lifespan <= 0)
|
||||||
|
@ -1165,8 +1165,8 @@ namespace NifOsg
|
||||||
created->setAlphaRange(osgParticle::rangef(1.f, 1.f));
|
created->setAlphaRange(osgParticle::rangef(1.f, 1.f));
|
||||||
|
|
||||||
float size = partctrl->size;
|
float size = partctrl->size;
|
||||||
if (particle.vertex < particledata->sizes.size())
|
if (particle.vertex < particledata->mSizes.size())
|
||||||
size *= particledata->sizes[particle.vertex];
|
size *= particledata->mSizes[particle.vertex];
|
||||||
|
|
||||||
created->setSizeRange(osgParticle::rangef(size, size));
|
created->setSizeRange(osgParticle::rangef(size, size));
|
||||||
box.expandBy(osg::BoundingSphere(position, size));
|
box.expandBy(osg::BoundingSphere(position, size));
|
||||||
|
@ -1394,8 +1394,8 @@ namespace NifOsg
|
||||||
if (!skin->mData.empty())
|
if (!skin->mData.empty())
|
||||||
{
|
{
|
||||||
data = skin->mData.getPtr();
|
data = skin->mData.getPtr();
|
||||||
if (!data->partitions.empty())
|
if (!data->mPartitions.empty())
|
||||||
partitions = data->partitions.getPtr();
|
partitions = data->mPartitions.getPtr();
|
||||||
}
|
}
|
||||||
if (!partitions && !skin->mPartitions.empty())
|
if (!partitions && !skin->mPartitions.empty())
|
||||||
partitions = skin->mPartitions.getPtr();
|
partitions = skin->mPartitions.getPtr();
|
||||||
|
@ -1556,14 +1556,9 @@ namespace NifOsg
|
||||||
std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->name);
|
std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->name);
|
||||||
|
|
||||||
SceneUtil::RigGeometry::BoneInfluence influence;
|
SceneUtil::RigGeometry::BoneInfluence influence;
|
||||||
const std::vector<Nif::NiSkinData::VertWeight>& weights = data->bones[i].weights;
|
influence.mWeights = data->mBones[i].mWeights;
|
||||||
for (size_t j = 0; j < weights.size(); j++)
|
influence.mInvBindMatrix = data->mBones[i].mTransform.toMatrix();
|
||||||
{
|
influence.mBoundSphere = data->mBones[i].mBoundSphere;
|
||||||
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);
|
|
||||||
|
|
||||||
map->mData.emplace_back(boneName, influence);
|
map->mData.emplace_back(boneName, influence);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue