mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-29 05:17:58 +03:00
Move particle geometry, add NiPSysData and NiPSysEmitterCtlrData
These record types are currently unreachable, might get tweaks later
This commit is contained in:
parent
ecc58c6011
commit
dddfbf806b
6 changed files with 167 additions and 100 deletions
|
@ -13,8 +13,8 @@ namespace Nif
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 114))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 114))
|
||||||
nif->read(mGroupId);
|
nif->read(mGroupId);
|
||||||
|
|
||||||
// Note: has special meaning for NiPSysData (unimplemented)
|
|
||||||
nif->read(mNumVertices);
|
nif->read(mNumVertices);
|
||||||
|
bool hasData = recType != RC_NiPSysData || nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO3;
|
||||||
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,7 @@ namespace Nif
|
||||||
nif->read(mCompressFlags);
|
nif->read(mCompressFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nif->get<bool>())
|
if (nif->get<bool>() && hasData)
|
||||||
nif->readVector(mVertices, mNumVertices);
|
nif->readVector(mVertices, mNumVertices);
|
||||||
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
||||||
|
@ -34,7 +34,7 @@ namespace Nif
|
||||||
nif->read(mMaterialHash);
|
nif->read(mMaterialHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nif->get<bool>())
|
if (nif->get<bool>() && hasData)
|
||||||
{
|
{
|
||||||
nif->readVector(mNormals, mNumVertices);
|
nif->readVector(mNormals, mNumVertices);
|
||||||
if (mDataFlags & DataFlag_HasTangents)
|
if (mDataFlags & DataFlag_HasTangents)
|
||||||
|
@ -46,7 +46,7 @@ namespace Nif
|
||||||
|
|
||||||
nif->read(mBoundingSphere);
|
nif->read(mBoundingSphere);
|
||||||
|
|
||||||
if (nif->get<bool>())
|
if (nif->get<bool>() && hasData)
|
||||||
nif->readVector(mColors, mNumVertices);
|
nif->readVector(mColors, mNumVertices);
|
||||||
|
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0))
|
if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0))
|
||||||
|
@ -64,13 +64,16 @@ namespace Nif
|
||||||
else if (!nif->get<bool>())
|
else if (!nif->get<bool>())
|
||||||
numUVs = 0;
|
numUVs = 0;
|
||||||
|
|
||||||
mUVList.resize(numUVs);
|
if (hasData)
|
||||||
for (std::vector<osg::Vec2f>& list : mUVList)
|
|
||||||
{
|
{
|
||||||
nif->readVector(list, mNumVertices);
|
mUVList.resize(numUVs);
|
||||||
// flip the texture coordinates to convert them to the OpenGL convention of bottom-left image origin
|
for (std::vector<osg::Vec2f>& list : mUVList)
|
||||||
for (osg::Vec2f& uv : list)
|
{
|
||||||
uv.y() = 1.f - uv.y();
|
nif->readVector(list, mNumVertices);
|
||||||
|
// flip the texture coordinates to convert them to the OpenGL convention of bottom-left image origin
|
||||||
|
for (osg::Vec2f& uv : list)
|
||||||
|
uv.y() = 1.f - uv.y();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
||||||
|
@ -146,64 +149,6 @@ namespace Nif
|
||||||
mLines.shrink_to_fit();
|
mLines.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiParticlesData::read(NIFStream* nif)
|
|
||||||
{
|
|
||||||
NiGeometryData::read(nif);
|
|
||||||
|
|
||||||
// Should always match the number of vertices in theory, but doesn't:
|
|
||||||
// see mist.nif in Mistify mod (https://www.nexusmods.com/morrowind/mods/48112).
|
|
||||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)
|
|
||||||
nif->read(mNumParticles);
|
|
||||||
bool isBs202 = nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() != 0;
|
|
||||||
|
|
||||||
bool numRadii = 1;
|
|
||||||
if (nif->getVersion() > NIFStream::generateVersion(10, 0, 1, 0))
|
|
||||||
numRadii = (nif->get<bool>() && !isBs202) ? mNumVertices : 0;
|
|
||||||
nif->readVector(mRadii, numRadii);
|
|
||||||
nif->read(mActiveCount);
|
|
||||||
if (nif->get<bool>() && !isBs202)
|
|
||||||
nif->readVector(mSizes, mNumVertices);
|
|
||||||
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
|
||||||
{
|
|
||||||
if (nif->get<bool>() && !isBs202)
|
|
||||||
nif->readVector(mRotations, mNumVertices);
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4))
|
|
||||||
{
|
|
||||||
if (nif->get<bool>() && !isBs202)
|
|
||||||
nif->readVector(mRotationAngles, mNumVertices);
|
|
||||||
if (nif->get<bool>() && !isBs202)
|
|
||||||
nif->readVector(mRotationAxes, mNumVertices);
|
|
||||||
if (isBs202)
|
|
||||||
{
|
|
||||||
nif->read(mHasTextureIndices);
|
|
||||||
uint32_t numSubtextureOffsets;
|
|
||||||
if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3)
|
|
||||||
numSubtextureOffsets = nif->get<uint8_t>();
|
|
||||||
else
|
|
||||||
nif->read(numSubtextureOffsets);
|
|
||||||
nif->readVector(mSubtextureOffsets, numSubtextureOffsets);
|
|
||||||
if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
|
||||||
{
|
|
||||||
nif->read(mAspectRatio);
|
|
||||||
nif->read(mAspectFlags);
|
|
||||||
nif->read(mAspectRatio2);
|
|
||||||
nif->read(mAspectSpeed);
|
|
||||||
nif->read(mAspectSpeed2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NiRotatingParticlesData::read(NIFStream* nif)
|
|
||||||
{
|
|
||||||
NiParticlesData::read(nif);
|
|
||||||
|
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0) && nif->get<bool>())
|
|
||||||
nif->readVector(mRotations, mNumVertices);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NiPosData::read(NIFStream* nif)
|
void NiPosData::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
mKeyList = std::make_shared<Vector3KeyMap>();
|
mKeyList = std::make_shared<Vector3KeyMap>();
|
||||||
|
|
|
@ -70,32 +70,6 @@ namespace Nif
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiParticlesData : public NiGeometryData
|
|
||||||
{
|
|
||||||
uint16_t mNumParticles{ 0 };
|
|
||||||
uint16_t mActiveCount;
|
|
||||||
|
|
||||||
std::vector<float> mRadii;
|
|
||||||
std::vector<float> mSizes;
|
|
||||||
std::vector<osg::Quat> mRotations;
|
|
||||||
std::vector<float> mRotationAngles;
|
|
||||||
std::vector<osg::Vec3f> mRotationAxes;
|
|
||||||
|
|
||||||
bool mHasTextureIndices{ false };
|
|
||||||
std::vector<osg::Vec4f> mSubtextureOffsets;
|
|
||||||
float mAspectRatio{ 1.f };
|
|
||||||
uint16_t mAspectFlags{ 0 };
|
|
||||||
float mAspectRatio2;
|
|
||||||
float mAspectSpeed, mAspectSpeed2;
|
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NiRotatingParticlesData : public NiParticlesData
|
|
||||||
{
|
|
||||||
void read(NIFStream* nif) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NiPosData : public Record
|
struct NiPosData : public Record
|
||||||
{
|
{
|
||||||
Vector3KeyMapPtr mKeyList;
|
Vector3KeyMapPtr mKeyList;
|
||||||
|
|
|
@ -240,14 +240,8 @@ namespace Nif
|
||||||
// GEOMETRY
|
// GEOMETRY
|
||||||
|
|
||||||
// 4.0.0.2
|
// 4.0.0.2
|
||||||
{ "NiAutoNormalParticles", &construct<NiParticles, RC_NiParticles> },
|
|
||||||
{ "NiAutoNormalParticlesData", &construct<NiParticlesData, RC_NiParticlesData> },
|
|
||||||
{ "NiLines", &construct<NiLines, RC_NiLines> },
|
{ "NiLines", &construct<NiLines, RC_NiLines> },
|
||||||
{ "NiLinesData", &construct<NiLinesData, RC_NiLinesData> },
|
{ "NiLinesData", &construct<NiLinesData, RC_NiLinesData> },
|
||||||
{ "NiParticles", &construct<NiParticles, RC_NiParticles> },
|
|
||||||
{ "NiParticlesData", &construct<NiParticlesData, RC_NiParticlesData> },
|
|
||||||
{ "NiRotatingParticles", &construct<NiParticles, RC_NiParticles> },
|
|
||||||
{ "NiRotatingParticlesData", &construct<NiRotatingParticlesData, RC_NiParticlesData> },
|
|
||||||
{ "NiSkinData", &construct<NiSkinData, RC_NiSkinData> },
|
{ "NiSkinData", &construct<NiSkinData, RC_NiSkinData> },
|
||||||
{ "NiSkinInstance", &construct<NiSkinInstance, RC_NiSkinInstance> },
|
{ "NiSkinInstance", &construct<NiSkinInstance, RC_NiSkinInstance> },
|
||||||
{ "NiSkinPartition", &construct<NiSkinPartition, RC_NiSkinPartition> },
|
{ "NiSkinPartition", &construct<NiSkinPartition, RC_NiSkinPartition> },
|
||||||
|
@ -265,12 +259,26 @@ namespace Nif
|
||||||
|
|
||||||
// PARTICLES
|
// PARTICLES
|
||||||
|
|
||||||
|
// Geometry, 4.0.0.2
|
||||||
|
{ "NiAutoNormalParticles", &construct<NiParticles, RC_NiParticles> },
|
||||||
|
{ "NiAutoNormalParticlesData", &construct<NiParticlesData, RC_NiParticlesData> },
|
||||||
|
{ "NiParticles", &construct<NiParticles, RC_NiParticles> },
|
||||||
|
{ "NiParticlesData", &construct<NiParticlesData, RC_NiParticlesData> },
|
||||||
|
{ "NiRotatingParticles", &construct<NiParticles, RC_NiParticles> },
|
||||||
|
{ "NiRotatingParticlesData", &construct<NiRotatingParticlesData, RC_NiParticlesData> },
|
||||||
|
|
||||||
|
// Geometry, Gamebryo
|
||||||
|
{ "NiPSysData", &construct<NiPSysData, RC_NiPSysData> },
|
||||||
|
|
||||||
// Modifiers, 4.0.0.2
|
// Modifiers, 4.0.0.2
|
||||||
{ "NiGravity", &construct<NiGravity, RC_NiGravity> },
|
{ "NiGravity", &construct<NiGravity, RC_NiGravity> },
|
||||||
{ "NiParticleColorModifier", &construct<NiParticleColorModifier, RC_NiParticleColorModifier> },
|
{ "NiParticleColorModifier", &construct<NiParticleColorModifier, RC_NiParticleColorModifier> },
|
||||||
{ "NiParticleGrowFade", &construct<NiParticleGrowFade, RC_NiParticleGrowFade> },
|
{ "NiParticleGrowFade", &construct<NiParticleGrowFade, RC_NiParticleGrowFade> },
|
||||||
{ "NiParticleRotation", &construct<NiParticleRotation, RC_NiParticleRotation> },
|
{ "NiParticleRotation", &construct<NiParticleRotation, RC_NiParticleRotation> },
|
||||||
|
|
||||||
|
// Modifier data, Gamebryo
|
||||||
|
{ "NiPSysEmitterCtlrData", &construct<NiPSysEmitterCtlrData, RC_NiPSysEmitterCtlrData> },
|
||||||
|
|
||||||
// Colliders, 4.0.0.2
|
// Colliders, 4.0.0.2
|
||||||
{ "NiPlanarCollider", &construct<NiPlanarCollider, RC_NiPlanarCollider> },
|
{ "NiPlanarCollider", &construct<NiPlanarCollider, RC_NiPlanarCollider> },
|
||||||
{ "NiSphericalCollider", &construct<NiSphericalCollider, RC_NiSphericalCollider> },
|
{ "NiSphericalCollider", &construct<NiSphericalCollider, RC_NiSphericalCollider> },
|
||||||
|
|
|
@ -92,4 +92,97 @@ namespace Nif
|
||||||
nif->read(mRotationSpeed);
|
nif->read(mRotationSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NiParticlesData::read(NIFStream* nif)
|
||||||
|
{
|
||||||
|
NiGeometryData::read(nif);
|
||||||
|
|
||||||
|
// Should always match the number of vertices in theory, but doesn't:
|
||||||
|
// see mist.nif in Mistify mod (https://www.nexusmods.com/morrowind/mods/48112).
|
||||||
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)
|
||||||
|
nif->read(mNumParticles);
|
||||||
|
bool isBs202 = nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() != 0;
|
||||||
|
|
||||||
|
bool numRadii = 1;
|
||||||
|
if (nif->getVersion() > NIFStream::generateVersion(10, 0, 1, 0))
|
||||||
|
numRadii = (nif->get<bool>() && !isBs202) ? mNumVertices : 0;
|
||||||
|
nif->readVector(mRadii, numRadii);
|
||||||
|
nif->read(mActiveCount);
|
||||||
|
if (nif->get<bool>() && !isBs202)
|
||||||
|
nif->readVector(mSizes, mNumVertices);
|
||||||
|
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
||||||
|
{
|
||||||
|
if (nif->get<bool>() && !isBs202)
|
||||||
|
nif->readVector(mRotations, mNumVertices);
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4))
|
||||||
|
{
|
||||||
|
if (nif->get<bool>() && !isBs202)
|
||||||
|
nif->readVector(mRotationAngles, mNumVertices);
|
||||||
|
if (nif->get<bool>() && !isBs202)
|
||||||
|
nif->readVector(mRotationAxes, mNumVertices);
|
||||||
|
if (isBs202)
|
||||||
|
{
|
||||||
|
nif->read(mHasTextureIndices);
|
||||||
|
uint32_t numSubtextureOffsets;
|
||||||
|
if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3)
|
||||||
|
numSubtextureOffsets = nif->get<uint8_t>();
|
||||||
|
else
|
||||||
|
nif->read(numSubtextureOffsets);
|
||||||
|
nif->readVector(mSubtextureOffsets, numSubtextureOffsets);
|
||||||
|
if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
||||||
|
{
|
||||||
|
nif->read(mAspectRatio);
|
||||||
|
nif->read(mAspectFlags);
|
||||||
|
nif->read(mAspectRatio2);
|
||||||
|
nif->read(mAspectSpeed);
|
||||||
|
nif->read(mAspectSpeed2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiRotatingParticlesData::read(NIFStream* nif)
|
||||||
|
{
|
||||||
|
NiParticlesData::read(nif);
|
||||||
|
|
||||||
|
if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0) && nif->get<bool>())
|
||||||
|
nif->readVector(mRotations, mNumVertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiPSysData::read(NIFStream* nif)
|
||||||
|
{
|
||||||
|
NiParticlesData::read(nif);
|
||||||
|
|
||||||
|
bool hasData = nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO3;
|
||||||
|
if (hasData)
|
||||||
|
{
|
||||||
|
mParticles.resize(mNumVertices);
|
||||||
|
for (NiParticleInfo& info : mParticles)
|
||||||
|
info.read(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_F76)
|
||||||
|
nif->skip(12); // Unknown
|
||||||
|
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 2) && nif->get<bool>() && hasData)
|
||||||
|
nif->readVector(mRotationSpeeds, mNumVertices);
|
||||||
|
|
||||||
|
if (nif->getVersion() != NIFStream::generateVersion(20, 2, 0, 7) || nif->getBethVersion() == 0)
|
||||||
|
{
|
||||||
|
nif->read(mNumAddedParticles);
|
||||||
|
nif->read(mAddedParticlesBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiPSysEmitterCtlrData::read(NIFStream* nif)
|
||||||
|
{
|
||||||
|
mFloatKeyList = std::make_shared<FloatKeyMap>();
|
||||||
|
mVisKeyList = std::make_shared<BoolKeyMap>();
|
||||||
|
uint32_t numVisKeys;
|
||||||
|
nif->read(numVisKeys);
|
||||||
|
for (size_t i = 0; i < numVisKeys; i++)
|
||||||
|
mVisKeyList->mKeys[nif->get<float>()].mValue = nif->get<uint8_t>() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define OPENMW_COMPONENTS_NIF_PARTICLE_HPP
|
#define OPENMW_COMPONENTS_NIF_PARTICLE_HPP
|
||||||
|
|
||||||
#include "base.hpp"
|
#include "base.hpp"
|
||||||
|
#include "data.hpp"
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
@ -86,5 +87,49 @@ namespace Nif
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NiParticlesData : NiGeometryData
|
||||||
|
{
|
||||||
|
uint16_t mNumParticles{ 0 };
|
||||||
|
uint16_t mActiveCount;
|
||||||
|
|
||||||
|
std::vector<float> mRadii;
|
||||||
|
std::vector<float> mSizes;
|
||||||
|
std::vector<osg::Quat> mRotations;
|
||||||
|
std::vector<float> mRotationAngles;
|
||||||
|
std::vector<osg::Vec3f> mRotationAxes;
|
||||||
|
|
||||||
|
bool mHasTextureIndices{ false };
|
||||||
|
std::vector<osg::Vec4f> mSubtextureOffsets;
|
||||||
|
float mAspectRatio{ 1.f };
|
||||||
|
uint16_t mAspectFlags{ 0 };
|
||||||
|
float mAspectRatio2;
|
||||||
|
float mAspectSpeed, mAspectSpeed2;
|
||||||
|
|
||||||
|
void read(NIFStream* nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NiRotatingParticlesData : NiParticlesData
|
||||||
|
{
|
||||||
|
void read(NIFStream* nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NiPSysData : NiParticlesData
|
||||||
|
{
|
||||||
|
std::vector<NiParticleInfo> mParticles;
|
||||||
|
std::vector<float> mRotationSpeeds;
|
||||||
|
uint16_t mNumAddedParticles;
|
||||||
|
uint16_t mAddedParticlesBase;
|
||||||
|
|
||||||
|
void read(NIFStream* nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NiPSysEmitterCtlrData : Record
|
||||||
|
{
|
||||||
|
FloatKeyMapPtr mFloatKeyList;
|
||||||
|
BoolKeyMapPtr mVisKeyList;
|
||||||
|
|
||||||
|
void read(NIFStream* nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -169,6 +169,8 @@ namespace Nif
|
||||||
RC_NiPlanarCollider,
|
RC_NiPlanarCollider,
|
||||||
RC_NiPoint3Interpolator,
|
RC_NiPoint3Interpolator,
|
||||||
RC_NiPosData,
|
RC_NiPosData,
|
||||||
|
RC_NiPSysEmitterCtlrData,
|
||||||
|
RC_NiPSysData,
|
||||||
RC_NiRollController,
|
RC_NiRollController,
|
||||||
RC_NiSequence,
|
RC_NiSequence,
|
||||||
RC_NiSequenceStreamHelper,
|
RC_NiSequenceStreamHelper,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue