mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 07:15:36 +00:00
Load SSE alchemy table
This commit is contained in:
parent
488657d9b4
commit
d2896945e8
16 changed files with 952 additions and 136 deletions
|
@ -35,8 +35,8 @@ namespace Nif::Testing
|
|||
inline void init(NiGeometry& value)
|
||||
{
|
||||
init(static_cast<Node&>(value));
|
||||
value.data = NiGeometryDataPtr(nullptr);
|
||||
value.skin = NiSkinInstancePtr(nullptr);
|
||||
value.mData = NiGeometryDataPtr(nullptr);
|
||||
value.mSkinInstance = NiSkinInstancePtr(nullptr);
|
||||
}
|
||||
|
||||
inline void init(NiTriShape& value)
|
||||
|
|
|
@ -326,20 +326,20 @@ namespace
|
|||
mNiTriShapeData.vertices = { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0) };
|
||||
mNiTriShapeData.mNumTriangles = 1;
|
||||
mNiTriShapeData.triangles = { 0, 1, 2 };
|
||||
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
mNiTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
|
||||
mNiTriShapeData2.recType = Nif::RC_NiTriShapeData;
|
||||
mNiTriShapeData2.vertices = { osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1) };
|
||||
mNiTriShapeData2.mNumTriangles = 1;
|
||||
mNiTriShapeData2.triangles = { 0, 1, 2 };
|
||||
mNiTriShape2.data = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
||||
mNiTriShape2.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
||||
|
||||
mNiTriStripsData.recType = Nif::RC_NiTriStripsData;
|
||||
mNiTriStripsData.vertices
|
||||
= { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0), osg::Vec3f(0, 1, 0) };
|
||||
mNiTriStripsData.mNumTriangles = 2;
|
||||
mNiTriStripsData.strips = { { 0, 1, 2, 3 } };
|
||||
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||
mNiTriStrips.mData = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -716,7 +716,7 @@ namespace
|
|||
TEST_F(TestBulletNifLoader,
|
||||
for_tri_shape_child_node_and_filename_starting_with_x_and_not_empty_skin_should_return_static_shape)
|
||||
{
|
||||
mNiTriShape.skin = Nif::NiSkinInstancePtr(&mNiSkinInstance);
|
||||
mNiTriShape.mSkinInstance = Nif::NiSkinInstancePtr(&mNiSkinInstance);
|
||||
mNiTriShape.parents.push_back(&mNiNode);
|
||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
|
||||
|
||||
|
@ -959,7 +959,7 @@ namespace
|
|||
|
||||
TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_empty_data_should_return_shape_with_null_collision_shape)
|
||||
{
|
||||
mNiTriShape.data = Nif::NiGeometryDataPtr(nullptr);
|
||||
mNiTriShape.mData = Nif::NiGeometryDataPtr(nullptr);
|
||||
mNiTriShape.parents.push_back(&mNiNode);
|
||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
|
||||
|
||||
|
@ -977,7 +977,7 @@ namespace
|
|||
TEST_F(TestBulletNifLoader,
|
||||
for_tri_shape_child_node_with_empty_data_triangles_should_return_shape_with_null_collision_shape)
|
||||
{
|
||||
auto data = static_cast<Nif::NiTriShapeData*>(mNiTriShape.data.getPtr());
|
||||
auto data = static_cast<Nif::NiTriShapeData*>(mNiTriShape.mData.getPtr());
|
||||
data->triangles.clear();
|
||||
mNiTriShape.parents.push_back(&mNiNode);
|
||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
|
||||
|
@ -1111,7 +1111,7 @@ namespace
|
|||
init(niTriShape);
|
||||
init(emptyCollisionNode);
|
||||
|
||||
niTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
niTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
niTriShape.parents.push_back(&mNiNode);
|
||||
|
||||
emptyCollisionNode.recType = Nif::RC_RootCollisionNode;
|
||||
|
@ -1210,7 +1210,7 @@ namespace
|
|||
|
||||
TEST_F(TestBulletNifLoader, should_ignore_tri_shape_data_with_mismatching_data_rec_type)
|
||||
{
|
||||
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||
mNiTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||
|
||||
Nif::NIFFile file("test.nif");
|
||||
file.mRoots.push_back(&mNiTriShape);
|
||||
|
@ -1245,7 +1245,7 @@ namespace
|
|||
|
||||
TEST_F(TestBulletNifLoader, should_ignore_tri_strips_data_with_mismatching_data_rec_type)
|
||||
{
|
||||
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
mNiTriStrips.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
|
||||
Nif::NIFFile file("test.nif");
|
||||
file.mRoots.push_back(&mNiTriStrips);
|
||||
|
|
|
@ -103,7 +103,7 @@ add_component_dir (sceneutil
|
|||
)
|
||||
|
||||
add_component_dir (nif
|
||||
controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream physics
|
||||
controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream physics particle
|
||||
)
|
||||
|
||||
add_component_dir (nifosg
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "controlled.hpp"
|
||||
#include "data.hpp"
|
||||
#include "node.hpp"
|
||||
#include "particle.hpp"
|
||||
#include "recordptr.hpp"
|
||||
|
||||
namespace Nif
|
||||
|
|
|
@ -46,29 +46,47 @@ namespace Nif
|
|||
|
||||
void NiGeometryData::read(NIFStream* nif)
|
||||
{
|
||||
bool isBS202 = nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0;
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 114))
|
||||
nif->getInt(); // Group ID. (Almost?) always 0.
|
||||
|
||||
int verts = nif->getUShort();
|
||||
unsigned short verts = 0;
|
||||
if ((nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO3 && NiPSysDataFlag) || !NiPSysDataFlag)
|
||||
{
|
||||
nif->read(verts);
|
||||
}
|
||||
|
||||
unsigned short BSMaxVertices = 0;
|
||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && NiPSysDataFlag
|
||||
&& nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO3)
|
||||
{
|
||||
nif->read(BSMaxVertices);
|
||||
}
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||
nif->skip(2); // Keep flags and compress flags
|
||||
|
||||
if (nif->getBoolean())
|
||||
bool hasVertices = true;
|
||||
hasVertices = nif->getBoolean();
|
||||
if (hasVertices)
|
||||
nif->getVector3s(vertices, verts);
|
||||
|
||||
unsigned int dataFlags = 0;
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
||||
dataFlags = nif->getUShort();
|
||||
unsigned short NiDataFlags = 0, BSDataFlags = 0;
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0) && !isBS202)
|
||||
nif->read(NiDataFlags);
|
||||
if (isBS202)
|
||||
nif->read(BSDataFlags);
|
||||
|
||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS
|
||||
&& nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
||||
nif->getUInt(); // Material CRC
|
||||
|
||||
if (nif->getBoolean())
|
||||
bool hasNormals;
|
||||
hasNormals = nif->getBoolean();
|
||||
if (hasNormals)
|
||||
{
|
||||
nif->getVector3s(normals, verts);
|
||||
if (dataFlags & 0x1000)
|
||||
if ((NiDataFlags | BSDataFlags) & 0x1000)
|
||||
{
|
||||
nif->getVector3s(tangents, verts);
|
||||
nif->getVector3s(bitangents, verts);
|
||||
|
@ -78,41 +96,36 @@ namespace Nif
|
|||
center = nif->getVector3();
|
||||
radius = nif->getFloat();
|
||||
|
||||
if (nif->getBoolean())
|
||||
bool hasVertexColors;
|
||||
hasVertexColors = nif->getBoolean();
|
||||
if (hasVertexColors)
|
||||
nif->getVector4s(colors, verts);
|
||||
|
||||
unsigned int numUVs = dataFlags;
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0))
|
||||
numUVs = nif->getUShort();
|
||||
nif->read(NiDataFlags);
|
||||
|
||||
unsigned short numUVs = (NiDataFlags & 0x3F) | (BSDataFlags & 0x1);
|
||||
// In Morrowind this field only corresponds to the number of UV sets.
|
||||
// In later games only the first 6 bits are used as a count and the rest are flags.
|
||||
if (nif->getVersion() > NIFFile::NIFVersion::VER_MW)
|
||||
{
|
||||
numUVs &= 0x3f;
|
||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0)
|
||||
numUVs &= 0x1;
|
||||
}
|
||||
|
||||
bool hasUVs = true;
|
||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)
|
||||
hasUVs = nif->getBoolean();
|
||||
if (hasUVs)
|
||||
// nif->read(hasUVs);
|
||||
nif->getBoolean(); // hasUVs
|
||||
|
||||
uvlist.resize(numUVs);
|
||||
for (unsigned int i = 0; i < numUVs; i++)
|
||||
{
|
||||
uvlist.resize(numUVs);
|
||||
for (unsigned int i = 0; i < numUVs; i++)
|
||||
nif->getVector2s(uvlist[i], verts);
|
||||
for (auto& uv : uvlist[i])
|
||||
{
|
||||
nif->getVector2s(uvlist[i], verts);
|
||||
// flip the texture coordinates to convert them to the OpenGL convention of bottom-left image origin
|
||||
for (unsigned int uv = 0; uv < uvlist[i].size(); ++uv)
|
||||
{
|
||||
uvlist[i][uv] = osg::Vec2f(uvlist[i][uv].x(), 1.f - uvlist[i][uv].y());
|
||||
}
|
||||
uv = osg::Vec2f(uv.x(), 1.f - uv.y());
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short consistencyFlag;
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
||||
nif->getUShort(); // Consistency flags
|
||||
nif->read(consistencyFlag);
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4))
|
||||
nif->skip(4); // Additional data
|
||||
|
@ -197,43 +210,6 @@ namespace Nif
|
|||
}
|
||||
}
|
||||
|
||||
void NiParticlesData::read(NIFStream* nif)
|
||||
{
|
||||
NiGeometryData::read(nif);
|
||||
|
||||
// Should always match the number of vertices
|
||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)
|
||||
numParticles = nif->getUShort();
|
||||
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(10, 0, 1, 0))
|
||||
std::fill(particleRadii.begin(), particleRadii.end(), nif->getFloat());
|
||||
else if (nif->getBoolean())
|
||||
nif->getFloats(particleRadii, vertices.size());
|
||||
activeCount = nif->getUShort();
|
||||
|
||||
// Particle sizes
|
||||
if (nif->getBoolean())
|
||||
nif->getFloats(sizes, vertices.size());
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0) && nif->getBoolean())
|
||||
nif->getQuaternions(rotations, vertices.size());
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4))
|
||||
{
|
||||
if (nif->getBoolean())
|
||||
nif->getFloats(rotationAngles, vertices.size());
|
||||
if (nif->getBoolean())
|
||||
nif->getVector3s(rotationAxes, vertices.size());
|
||||
}
|
||||
}
|
||||
|
||||
void NiRotatingParticlesData::read(NIFStream* nif)
|
||||
{
|
||||
NiParticlesData::read(nif);
|
||||
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0) && nif->getBoolean())
|
||||
nif->getQuaternions(rotations, vertices.size());
|
||||
}
|
||||
|
||||
void NiPosData::read(NIFStream* nif)
|
||||
{
|
||||
mKeyList = std::make_shared<Vector3KeyMap>();
|
||||
|
@ -561,5 +537,4 @@ namespace Nif
|
|||
mCenter = nif->getVector3();
|
||||
mRadius = nif->getFloat();
|
||||
}
|
||||
|
||||
} // Namespace
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "nifkey.hpp"
|
||||
#include "niftypes.hpp" // Transformation
|
||||
#include "recordptr.hpp"
|
||||
#include <components/nif/controller.hpp>
|
||||
#include <components/nif/node.hpp>
|
||||
|
||||
namespace Nif
|
||||
|
@ -41,6 +42,8 @@ namespace Nif
|
|||
osg::Vec3f center;
|
||||
float radius;
|
||||
|
||||
bool NiPSysDataFlag = false;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
|
@ -76,24 +79,6 @@ namespace Nif
|
|||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiParticlesData : public NiGeometryData
|
||||
{
|
||||
int numParticles{ 0 };
|
||||
|
||||
int activeCount{ 0 };
|
||||
|
||||
std::vector<float> particleRadii, sizes, rotationAngles;
|
||||
std::vector<osg::Quat> rotations;
|
||||
std::vector<osg::Vec3f> rotationAxes;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiRotatingParticlesData : public NiParticlesData
|
||||
{
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiPosData : public Record
|
||||
{
|
||||
Vector3KeyMapPtr mKeyList;
|
||||
|
@ -329,6 +314,5 @@ namespace Nif
|
|||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
} // Namespace
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "exception.hpp"
|
||||
#include "extra.hpp"
|
||||
#include "node.hpp"
|
||||
#include "particle.hpp"
|
||||
#include "physics.hpp"
|
||||
#include "property.hpp"
|
||||
|
||||
|
@ -217,6 +218,26 @@ namespace Nif
|
|||
{ "BSLightingShaderPropertyColorController",
|
||||
&construct<BSEffectShaderPropertyColorController, RC_BSLightingShaderPropertyColorController> },
|
||||
{ "BSBehaviorGraphExtraData", &construct<BSBehaviorGraphExtraData, RC_BSBehaviorGraphExtraData> },
|
||||
{ "NiPSysData", &construct<NiPSysData, RC_NiPSysData> },
|
||||
{ "NiParticleSystem", &construct<NiParticleSystem, RC_NiParticleSystem> },
|
||||
{ "NiPSysEmitterCtlr", &construct<NiPSysEmitterCtlr, RC_NiPSysEmitterCtlr> },
|
||||
{ "NiPSysUpdateCtlr", &construct<Controller, RC_Controller> },
|
||||
{ "NiPSysAgeDeathModifier", &construct<NiPSysAgeDeathModifier, RC_NiPSysAgeDeathModifier> },
|
||||
{ "BSPSysLODModifier", &construct<BSPSysLODModifier, RC_BSPSysLODModifier> },
|
||||
{ "NiPSysCylinderEmitter", &construct<NiPSysCylinderEmitter, RC_NiPSysCylinderEmitter> },
|
||||
{ "NiPSysSpawnModifier", &construct<NiPSysSpawnModifier, RC_NiPSysSpawnModifier> },
|
||||
{ "BSPSysSimpleColorModifier", &construct<BSPSysSimpleColorModifier, RC_BSPSysSimpleColorModifier> },
|
||||
{ "NiPSysRotationModifier", &construct<NiPSysRotationModifier, RC_NiPSysRotationModifier> },
|
||||
{ "BSPSysScaleModifier", &construct<BSPSysScaleModifier, RC_BSPSysScaleModifier> },
|
||||
{ "NiPSysGravityModifier", &construct<NiPSysGravityModifier, RC_NiPSysGravityModifier> },
|
||||
{ "NiPSysPositionModifier", &construct<NiPSysModifier, RC_NiPSysModifier> },
|
||||
{ "NiPSysBoundUpdateModifier", &construct<NiPSysBoundUpdateModifier, RC_NiPSysBoundUpdateModifier> },
|
||||
{ "NiPSysModifierActiveCtlr", &construct<NiPSysModifierActiveCtlr, RC_NiPSysModifierActiveCtlr> },
|
||||
{ "NiPSysMeshEmitter", &construct<NiPSysMeshEmitter, RC_NiPSysMeshEmitter> },
|
||||
{ "BSPSysInheritVelocityModifier",
|
||||
&construct<BSPSysInheritVelocityModifier, RC_BSPSysInheritVelocityModifier> },
|
||||
{ "NiPSysBombModifier", &construct<NiPSysBombModifier, RC_NiPSysBombModifier> },
|
||||
{ "NiPSysDragModifier", &construct<NiPSysDragModifier, RC_NiPSysDragModifier> },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ namespace Nif
|
|||
data = readLittleEndianType<T>(inp);
|
||||
}
|
||||
|
||||
void read(osg::Vec2f& data) { readLittleEndianBufferOfType<2, float>(inp, data._v); }
|
||||
void read(osg::Vec3f& data) { readLittleEndianBufferOfType<3, float>(inp, data._v); }
|
||||
void read(osg::Vec4f& data) { readLittleEndianBufferOfType<4, float>(inp, data._v); }
|
||||
|
||||
|
|
|
@ -171,25 +171,48 @@ namespace Nif
|
|||
void NiGeometry::read(NIFStream* nif)
|
||||
{
|
||||
Node::read(nif);
|
||||
data.read(nif);
|
||||
skin.read(nif);
|
||||
material.read(nif);
|
||||
|
||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && NiParticleSystemFlag)
|
||||
{
|
||||
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SSE)
|
||||
mBoundingVolume.read(nif);
|
||||
|
||||
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_F76)
|
||||
nif->read(mBoundMinMax);
|
||||
|
||||
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SSE)
|
||||
mSkin.read(nif);
|
||||
}
|
||||
|
||||
bool SSE_flag = (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SSE && !NiParticleSystemFlag
|
||||
&& nif->getVersion() == NIFFile::NIFVersion::VER_BGS);
|
||||
if (nif->getBethVersion() < NIFFile::BethVersion::BETHVER_SSE || SSE_flag)
|
||||
mData.read(nif);
|
||||
if ((nif->getBethVersion() < NIFFile::BethVersion::BETHVER_SSE
|
||||
&& nif->getVersion() > NIFStream::generateVersion(3, 3, 0, 13))
|
||||
|| SSE_flag)
|
||||
mSkinInstance.read(nif);
|
||||
if ((nif->getBethVersion() < NIFFile::BethVersion::BETHVER_SSE
|
||||
&& nif->getVersion() > NIFStream::generateVersion(10, 0, 1, 0))
|
||||
|| SSE_flag)
|
||||
material.read(nif);
|
||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS
|
||||
&& nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
||||
{
|
||||
shaderprop.read(nif);
|
||||
alphaprop.read(nif);
|
||||
mShaderProperty.read(nif);
|
||||
mAlphaProperty.read(nif);
|
||||
}
|
||||
}
|
||||
|
||||
void NiGeometry::post(Reader& nif)
|
||||
{
|
||||
Node::post(nif);
|
||||
data.post(nif);
|
||||
skin.post(nif);
|
||||
shaderprop.post(nif);
|
||||
alphaprop.post(nif);
|
||||
if (recType != RC_NiParticles && !skin.empty())
|
||||
mData.post(nif);
|
||||
mSkin.post(nif);
|
||||
mSkinInstance.post(nif);
|
||||
mShaderProperty.post(nif);
|
||||
mAlphaProperty.post(nif);
|
||||
if (recType != RC_NiParticles && !mSkinInstance.empty())
|
||||
nif.setUseSkinning(true);
|
||||
}
|
||||
|
||||
|
@ -387,7 +410,9 @@ namespace Nif
|
|||
nif->read(mParticleDataSize);
|
||||
if (mParticleDataSize > 0)
|
||||
{
|
||||
throw Nif::Exception("Unhandled Particle Data in BSTriShape: ", nif->getFile().getFilename());
|
||||
nif->getVector3s(mParticleVerts, vertNum);
|
||||
// nif->readVector(mParticleNormals, vertNum); //Documentation seems to be wrong about this one
|
||||
nif->readVector(mParticleTriangles, triNum * 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define OPENMW_COMPONENTS_NIF_NODE_HPP
|
||||
|
||||
#include <array>
|
||||
#include <components/nif/recordptr.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <osg/Plane>
|
||||
|
@ -151,11 +152,17 @@ namespace Nif
|
|||
void read(NIFStream* nif);
|
||||
};
|
||||
|
||||
NiGeometryDataPtr data;
|
||||
NiSkinInstancePtr skin;
|
||||
NiGeometryDataPtr mData;
|
||||
NiSkinInstancePtr mSkinInstance;
|
||||
RecordPtr mSkin;
|
||||
MaterialData material;
|
||||
BSShaderPropertyPtr shaderprop;
|
||||
NiAlphaPropertyPtr alphaprop;
|
||||
BSShaderPropertyPtr mShaderProperty;
|
||||
NiAlphaPropertyPtr mAlphaProperty;
|
||||
|
||||
NiBoundingVolume::NiSphereBV mBoundingVolume;
|
||||
float mBoundMinMax;
|
||||
|
||||
bool NiParticleSystemFlag = false;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
|
@ -175,9 +182,6 @@ namespace Nif
|
|||
struct NiLines : NiGeometry
|
||||
{
|
||||
};
|
||||
struct NiParticles : NiGeometry
|
||||
{
|
||||
};
|
||||
|
||||
struct NiCamera : Node
|
||||
{
|
||||
|
|
483
components/nif/particle.cpp
Normal file
483
components/nif/particle.cpp
Normal file
|
@ -0,0 +1,483 @@
|
|||
#include "particle.hpp"
|
||||
#include <components/nif/exception.hpp>
|
||||
|
||||
namespace Nif
|
||||
{
|
||||
void NiParticlesData::read(NIFStream* nif)
|
||||
{
|
||||
bool isBS202 = nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0;
|
||||
// if (nif->getVersion() < NIFFile::NIFVersion::VER_BGS)
|
||||
NiGeometryData::read(nif);
|
||||
|
||||
// Should always match the number of vertices
|
||||
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)
|
||||
nif->read(numParticles);
|
||||
|
||||
float particleRadius;
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(10, 0, 1, 0))
|
||||
{
|
||||
nif->read(particleRadius);
|
||||
particleRadii.resize(vertices.size());
|
||||
std::fill(particleRadii.begin(), particleRadii.end(), particleRadius);
|
||||
}
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||
{
|
||||
bool hasRadii = nif->getBoolean();
|
||||
// nif->read(hasRadii);
|
||||
if (hasRadii && !isBS202)
|
||||
nif->readVector(particleRadii, vertices.size());
|
||||
}
|
||||
activeCount = nif->getUShort();
|
||||
|
||||
// Particle sizes
|
||||
bool hasSizes;
|
||||
hasSizes = nif->getBoolean();
|
||||
if (hasSizes && !isBS202)
|
||||
nif->readVector(sizes, vertices.size());
|
||||
|
||||
bool hasRotations = false;
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
||||
{
|
||||
hasRotations = nif->getBoolean();
|
||||
if (hasRotations && !isBS202)
|
||||
{
|
||||
nif->getQuaternions(mRotations, vertices.size());
|
||||
}
|
||||
}
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4))
|
||||
{
|
||||
bool hasRotationAngles, hasRotationAxes;
|
||||
|
||||
// nif->read(hasRotationAngles);
|
||||
hasRotationAngles = nif->getBoolean();
|
||||
if (hasRotationAngles && !isBS202)
|
||||
nif->readVector(mRotationAngles, vertices.size());
|
||||
|
||||
// nif->read(hasRotationAxes);
|
||||
hasRotationAxes = nif->getBoolean();
|
||||
if (hasRotationAxes && !isBS202)
|
||||
{
|
||||
nif->getVector3s(mRotationAxes, vertices.size());
|
||||
}
|
||||
}
|
||||
|
||||
bool hasTexIndices = false;
|
||||
if (isBS202)
|
||||
nif->read(hasTexIndices);
|
||||
|
||||
unsigned int subtexOffsetNum = 0;
|
||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS)
|
||||
{
|
||||
if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
||||
nif->read(subtexOffsetNum);
|
||||
else if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3 && isBS202)
|
||||
subtexOffsetNum = nif->get<char>();
|
||||
}
|
||||
|
||||
if (isBS202)
|
||||
nif->getVector4s(mSubtexOffsets, subtexOffsetNum);
|
||||
|
||||
if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3
|
||||
&& nif->getVersion() == NIFFile::NIFVersion::VER_BGS)
|
||||
{
|
||||
nif->read(mAspectRatio);
|
||||
|
||||
nif->read(mAspectFlags);
|
||||
|
||||
nif->read(mAspect2);
|
||||
nif->read(mSpeed1);
|
||||
nif->read(mSpeed2);
|
||||
}
|
||||
}
|
||||
|
||||
void NiRotatingParticlesData::read(NIFStream* nif)
|
||||
{
|
||||
NiParticlesData::read(nif);
|
||||
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0) && nif->getBoolean())
|
||||
nif->getQuaternions(mRotations, vertices.size());
|
||||
}
|
||||
|
||||
void NiParticleInfo::read(NIFStream* nif)
|
||||
{
|
||||
nif->read(mVelocity);
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(10, 4, 0, 1))
|
||||
nif->read(mRotation);
|
||||
nif->read(mAge);
|
||||
nif->read(mLifeSpan);
|
||||
nif->read(mLastUpdate);
|
||||
nif->read(mSpawnGen);
|
||||
nif->read(mCode);
|
||||
}
|
||||
|
||||
void NiPSysData::read(NIFStream* nif)
|
||||
{
|
||||
bool isBS202 = nif->getVersion() == NIFStream::generateVersion(20, 2, 0, 7) && nif->getBethVersion() > 0;
|
||||
NiPSysDataFlag = true;
|
||||
NiParticlesData::read(nif);
|
||||
|
||||
if (nif->getVersion() != NIFStream::generateVersion(20, 2, 0, 7))
|
||||
{
|
||||
mParticleInfo.resize(vertices.size());
|
||||
for (unsigned long i = 0; i < vertices.size(); i++)
|
||||
{
|
||||
NiParticleInfo temp;
|
||||
temp.read(nif);
|
||||
mParticleInfo[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_F76)
|
||||
nif->skip(sizeof(float) * 3);
|
||||
|
||||
if (nif->getVersion() == NIFStream::generateVersion(20, 2, 4, 7))
|
||||
nif->skip(1);
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 2))
|
||||
{
|
||||
bool hasRotationSpeed;
|
||||
nif->read(hasRotationSpeed);
|
||||
if (hasRotationSpeed && !isBS202)
|
||||
{
|
||||
mRotationSpeeds.resize(vertices.size());
|
||||
nif->readVector(mRotationSpeeds, vertices.size());
|
||||
}
|
||||
}
|
||||
|
||||
if (!isBS202)
|
||||
{
|
||||
nif->read(mParticlesAddedNum);
|
||||
nif->read(mParticlesBase);
|
||||
}
|
||||
|
||||
if (nif->getVersion() == NIFStream::generateVersion(20, 2, 4, 7))
|
||||
nif->skip(1);
|
||||
}
|
||||
|
||||
void NiParticleSystem::read(NIFStream* nif)
|
||||
{
|
||||
NiParticleSystemFlag = true;
|
||||
NiParticles::read(nif);
|
||||
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SSE)
|
||||
mVertexDesc.read(nif);
|
||||
|
||||
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SKY)
|
||||
{
|
||||
nif->read(mFarBegin);
|
||||
nif->read(mFarEnd);
|
||||
nif->read(mNearBegin);
|
||||
nif->read(mNearEnd);
|
||||
}
|
||||
|
||||
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SSE)
|
||||
mNiPSysData.read(nif);
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||
{
|
||||
nif->read(mWorldSpace);
|
||||
unsigned int modifierNum;
|
||||
nif->read(modifierNum);
|
||||
mModifiers.resize(modifierNum);
|
||||
|
||||
for (auto& modifier : mModifiers)
|
||||
{
|
||||
modifier.read(nif);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NiParticleSystem::post(Reader& nif)
|
||||
{
|
||||
NiParticles::post(nif);
|
||||
mNiPSysData.post(nif);
|
||||
for (auto ptr : mModifiers)
|
||||
{
|
||||
ptr.post(nif);
|
||||
}
|
||||
}
|
||||
|
||||
void NiPSysModifier::read(NIFStream* nif)
|
||||
{
|
||||
mName = nif->getString();
|
||||
nif->read(mOrder);
|
||||
mTarget.read(nif);
|
||||
nif->read(mActive);
|
||||
}
|
||||
|
||||
void NiPSysModifier::post(Reader& nif)
|
||||
{
|
||||
mTarget.post(nif);
|
||||
}
|
||||
|
||||
void NiPSysModifierCtlr::read(NIFStream* nif)
|
||||
{
|
||||
NiSingleInterpController::read(nif);
|
||||
mModifierName = nif->getString();
|
||||
}
|
||||
|
||||
void NiPSysEmitterCtlr::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifierCtlr::read(nif);
|
||||
if (nif->getVersion() > NIFStream::generateVersion(10, 1, 0, 103))
|
||||
mVisibilityInterpolator.read(nif);
|
||||
// TODO: Handle pre 10.1.0.103
|
||||
}
|
||||
|
||||
void NiPSysEmitterCtlr::post(Reader& nif)
|
||||
{
|
||||
NiPSysModifierCtlr::post(nif);
|
||||
if (nif.getVersion() > NIFStream::generateVersion(10, 1, 0, 103))
|
||||
mVisibilityInterpolator.post(nif);
|
||||
}
|
||||
|
||||
void NiPSysAgeDeathModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
nif->read(mSpawnOnDeath);
|
||||
mSpawnModifier.read(nif);
|
||||
}
|
||||
|
||||
void NiPSysAgeDeathModifier::post(Reader& nif)
|
||||
{
|
||||
mSpawnModifier.post(nif);
|
||||
}
|
||||
|
||||
void NiPSysSpawnModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
nif->read(mNumSpawnGens);
|
||||
nif->read(mPercentSpawned);
|
||||
nif->read(mMinSpawnNum);
|
||||
nif->read(mMaxSpawnNum);
|
||||
nif->read(mSpawnSpeedVariation);
|
||||
nif->read(mSpawnDirVariation);
|
||||
nif->read(mLifeSpan);
|
||||
nif->read(mLifeSpanVariation);
|
||||
}
|
||||
|
||||
void BSPSysLODModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
nif->read(mBeginDist);
|
||||
nif->read(mEndDist);
|
||||
nif->read(mEndEmitScale);
|
||||
nif->read(mEndSize);
|
||||
}
|
||||
|
||||
void NiPSysCylinderEmitter::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysVolumeEmitter::read(nif);
|
||||
|
||||
nif->read(mRadius);
|
||||
nif->read(mHeight);
|
||||
}
|
||||
|
||||
void NiPSysVolumeEmitter::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysEmitter::read(nif);
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||
mEmitterObject.read(nif);
|
||||
}
|
||||
|
||||
void NiPSysVolumeEmitter::post(Reader& nif)
|
||||
{
|
||||
NiPSysEmitter::post(nif);
|
||||
|
||||
if (nif.getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||
mEmitterObject.post(nif);
|
||||
}
|
||||
|
||||
void NiPSysEmitter::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
nif->read(mSpeed);
|
||||
nif->read(mSpeedVariation);
|
||||
nif->read(mDeclination);
|
||||
nif->read(mDeclinationVariation);
|
||||
nif->read(mPlanarAngle);
|
||||
nif->read(mPlanarAngleVariation);
|
||||
nif->read(mInitialColor);
|
||||
nif->read(mInitialRadius);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 4, 0, 1))
|
||||
nif->read(mRadiusVariation);
|
||||
nif->read(mLifespan);
|
||||
nif->read(mLifespanVariation);
|
||||
// nif->skip(sizeof(float) * 2);
|
||||
}
|
||||
|
||||
void BSPSysSimpleColorModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
nif->read(mFadeInPercent);
|
||||
nif->read(mFadeOutPercent);
|
||||
nif->read(mColor1EndPercent);
|
||||
nif->read(mColor1StartPercent);
|
||||
nif->read(mColor2EndPercent);
|
||||
nif->read(mColor2StartPercent);
|
||||
nif->getVector4s(mColors, 3);
|
||||
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_F76)
|
||||
nif->skip(sizeof(unsigned short) * 26);
|
||||
}
|
||||
|
||||
void NiPSysRotationModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
nif->read(mRotationSpeed);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 2))
|
||||
nif->read(mRotationSpeedVariation);
|
||||
|
||||
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_F76)
|
||||
throw Nif::Exception("Fallout76 is unsupported: ", nif->getFile().getFilename());
|
||||
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 2))
|
||||
{
|
||||
nif->read(mRotationAngle);
|
||||
nif->read(mRotationAngleVariation);
|
||||
mRandRotSpeedSign = nif->getBoolean();
|
||||
}
|
||||
|
||||
mRandAxis = nif->getBoolean();
|
||||
nif->read(mAxis);
|
||||
}
|
||||
|
||||
void BSPSysScaleModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
unsigned int numScales;
|
||||
nif->read(numScales);
|
||||
nif->readVector(mScales, numScales);
|
||||
}
|
||||
|
||||
void NiPSysGravityModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
mGravityObject.read(nif);
|
||||
nif->read(mGravityAxis);
|
||||
nif->read(mDecay);
|
||||
nif->read(mStrength);
|
||||
nif->read(mForceType);
|
||||
nif->read(mTurbulence);
|
||||
nif->read(mTurbulenceScale);
|
||||
|
||||
if (nif->getBethVersion() > 16)
|
||||
mWorldAligned = nif->getBoolean();
|
||||
}
|
||||
|
||||
void NiPSysGravityModifier::post(Reader& nif)
|
||||
{
|
||||
NiPSysModifier::post(nif);
|
||||
|
||||
mGravityObject.post(nif);
|
||||
}
|
||||
|
||||
void NiPSysBoundUpdateModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
nif->read(mUpdateSkip);
|
||||
}
|
||||
|
||||
void NiPSysModifierActiveCtlr::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifierCtlr::read(nif);
|
||||
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
|
||||
mNiVisData.read(nif);
|
||||
}
|
||||
|
||||
void NiPSysModifierActiveCtlr::post(Reader& nif)
|
||||
{
|
||||
NiPSysModifierCtlr::post(nif);
|
||||
|
||||
if (nif.getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
|
||||
mNiVisData.post(nif);
|
||||
}
|
||||
|
||||
void NiPSysMeshEmitter::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysEmitter::read(nif);
|
||||
|
||||
unsigned int meshNum;
|
||||
nif->read(meshNum);
|
||||
|
||||
mEmitterMeshes.resize(meshNum);
|
||||
for (auto& mesh : mEmitterMeshes)
|
||||
mesh.read(nif);
|
||||
|
||||
nif->read(mInitialVelocityType);
|
||||
nif->read(mEmissionType);
|
||||
nif->read(mEmissionAxis);
|
||||
}
|
||||
|
||||
void NiPSysMeshEmitter::post(Reader& nif)
|
||||
{
|
||||
NiPSysEmitter::post(nif);
|
||||
|
||||
for (auto& mesh : mEmitterMeshes)
|
||||
mesh.post(nif);
|
||||
}
|
||||
|
||||
void BSPSysInheritVelocityModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
mInheritObject.read(nif);
|
||||
nif->read(mInheritChance);
|
||||
nif->read(mVelocityMult);
|
||||
nif->read(mVelcoityVariation);
|
||||
}
|
||||
|
||||
void BSPSysInheritVelocityModifier::post(Reader& nif)
|
||||
{
|
||||
NiPSysModifier::post(nif);
|
||||
|
||||
mInheritObject.post(nif);
|
||||
}
|
||||
|
||||
void NiPSysBombModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
mBombObj.read(nif);
|
||||
nif->read(mBombAxis);
|
||||
nif->read(mDecay);
|
||||
nif->read(mDeltaV);
|
||||
nif->read(mDecayType);
|
||||
nif->read(mSymmetryType);
|
||||
}
|
||||
|
||||
void NiPSysBombModifier::post(Reader& nif)
|
||||
{
|
||||
NiPSysModifier::post(nif);
|
||||
|
||||
mBombObj.post(nif);
|
||||
}
|
||||
|
||||
void NiPSysDragModifier::read(NIFStream* nif)
|
||||
{
|
||||
NiPSysModifier::read(nif);
|
||||
|
||||
mDragObj.read(nif);
|
||||
nif->read(mDragAxis);
|
||||
nif->read(mPercentage);
|
||||
nif->read(mRange);
|
||||
nif->read(mRangeFalloff);
|
||||
}
|
||||
|
||||
void NiPSysDragModifier::post(Reader& nif)
|
||||
{
|
||||
NiPSysModifier::post(nif);
|
||||
|
||||
mDragObj.post(nif);
|
||||
}
|
||||
}
|
289
components/nif/particle.hpp
Normal file
289
components/nif/particle.hpp
Normal file
|
@ -0,0 +1,289 @@
|
|||
|
||||
#ifndef OPENMW_COMPONENTS_NIF_PARTICLE_HPP
|
||||
#define OPENMW_COMPONENTS_NIF_PARTICLE_HPP
|
||||
|
||||
#include "nifkey.hpp"
|
||||
#include "niftypes.hpp" // Transformation
|
||||
#include "recordptr.hpp"
|
||||
#include <components/nif/controller.hpp>
|
||||
#include <components/nif/data.hpp>
|
||||
#include <components/nif/node.hpp>
|
||||
#include <components/settings/values.hpp>
|
||||
|
||||
namespace Nif
|
||||
{
|
||||
struct NiParticles : NiGeometry
|
||||
{
|
||||
};
|
||||
|
||||
struct NiParticlesData : public NiGeometryData
|
||||
{
|
||||
unsigned short numParticles{ 0 };
|
||||
|
||||
int activeCount{ 0 };
|
||||
|
||||
std::vector<float> particleRadii, sizes, mRotationAngles;
|
||||
std::vector<osg::Quat> mRotations;
|
||||
std::vector<osg::Vec3f> mRotationAxes;
|
||||
std::vector<osg::Vec4f> mSubtexOffsets;
|
||||
|
||||
float mAspectRatio;
|
||||
unsigned short mAspectFlags;
|
||||
float mAspect2, mSpeed1, mSpeed2;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiRotatingParticlesData : public NiParticlesData
|
||||
{
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiParticleInfo
|
||||
{
|
||||
osg::Vec3f mVelocity;
|
||||
osg::Vec3f mRotation;
|
||||
float mAge;
|
||||
float mLifeSpan;
|
||||
float mLastUpdate;
|
||||
unsigned short mSpawnGen;
|
||||
unsigned short mCode;
|
||||
|
||||
void read(NIFStream* nif);
|
||||
};
|
||||
|
||||
struct NiPSysData : public NiParticlesData
|
||||
{
|
||||
std::vector<NiParticleInfo> mParticleInfo;
|
||||
std::vector<float> mRotationSpeeds;
|
||||
unsigned short mParticlesAddedNum;
|
||||
unsigned short mParticlesBase;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiParticleSystem : public NiParticles
|
||||
{
|
||||
BSVertexDesc mVertexDesc;
|
||||
unsigned short mFarBegin;
|
||||
unsigned short mFarEnd;
|
||||
unsigned short mNearBegin;
|
||||
unsigned short mNearEnd;
|
||||
NiPSysDataPtr mNiPSysData;
|
||||
|
||||
bool mWorldSpace;
|
||||
std::vector<NiPSysModifierPtr> mModifiers;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysModifier : public Record
|
||||
{
|
||||
std::string mName;
|
||||
unsigned int mOrder;
|
||||
NiParticleSystemPtr mTarget;
|
||||
bool mActive;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysModifierCtlr : public NiSingleInterpController
|
||||
{
|
||||
std::string mModifierName;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysEmitterCtlr : public NiPSysModifierCtlr
|
||||
{
|
||||
NiInterpolatorPtr mVisibilityInterpolator;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysAgeDeathModifier : public NiPSysModifier
|
||||
{
|
||||
bool mSpawnOnDeath;
|
||||
NiPSysSpawnModifierPtr mSpawnModifier;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysSpawnModifier : public NiPSysModifier
|
||||
{
|
||||
unsigned short mNumSpawnGens;
|
||||
float mPercentSpawned;
|
||||
unsigned short mMinSpawnNum, mMaxSpawnNum;
|
||||
float mSpawnSpeedVariation;
|
||||
float mSpawnDirVariation;
|
||||
float mLifeSpan;
|
||||
float mLifeSpanVariation;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct BSPSysLODModifier : public NiPSysModifier
|
||||
{
|
||||
float mBeginDist;
|
||||
float mEndDist;
|
||||
float mEndEmitScale;
|
||||
float mEndSize;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysEmitter : public NiPSysModifier
|
||||
{
|
||||
float mSpeed;
|
||||
float mSpeedVariation;
|
||||
float mDeclination;
|
||||
float mDeclinationVariation;
|
||||
float mPlanarAngle;
|
||||
float mPlanarAngleVariation;
|
||||
|
||||
osg::Vec4f mInitialColor;
|
||||
|
||||
float mInitialRadius;
|
||||
float mRadiusVariation;
|
||||
float mLifespan;
|
||||
float mLifespanVariation;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysVolumeEmitter : public NiPSysEmitter
|
||||
{
|
||||
NiNodePtr mEmitterObject;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysCylinderEmitter : public NiPSysVolumeEmitter
|
||||
{
|
||||
float mRadius;
|
||||
float mHeight;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct BSPSysSimpleColorModifier : public NiPSysModifier
|
||||
{
|
||||
float mFadeInPercent;
|
||||
float mFadeOutPercent;
|
||||
float mColor1EndPercent;
|
||||
float mColor1StartPercent;
|
||||
float mColor2EndPercent;
|
||||
float mColor2StartPercent;
|
||||
|
||||
std::vector<osg::Vec4f> mColors;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysRotationModifier : public NiPSysModifier
|
||||
{
|
||||
float mRotationSpeed;
|
||||
float mRotationSpeedVariation;
|
||||
float mRotationAngle;
|
||||
float mRotationAngleVariation;
|
||||
|
||||
bool mRandRotSpeedSign;
|
||||
bool mRandAxis;
|
||||
osg::Vec3f mAxis;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct BSPSysScaleModifier : public NiPSysModifier
|
||||
{
|
||||
std::vector<float> mScales;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysGravityModifier : public NiPSysModifier
|
||||
{
|
||||
NamedPtr mGravityObject;
|
||||
osg::Vec3f mGravityAxis;
|
||||
float mDecay;
|
||||
float mStrength;
|
||||
unsigned int mForceType;
|
||||
float mTurbulence;
|
||||
float mTurbulenceScale;
|
||||
|
||||
bool mWorldAligned;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysBoundUpdateModifier : public NiPSysModifier
|
||||
{
|
||||
unsigned short mUpdateSkip;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysModifierActiveCtlr : public NiPSysModifierCtlr
|
||||
{
|
||||
NiVisDataPtr mNiVisData;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysMeshEmitter : public NiPSysEmitter
|
||||
{
|
||||
std::vector<NamedPtr> mEmitterMeshes;
|
||||
unsigned int mInitialVelocityType;
|
||||
unsigned int mEmissionType;
|
||||
osg::Vec3f mEmissionAxis;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct BSPSysInheritVelocityModifier : public NiPSysModifier
|
||||
{
|
||||
NamedPtr mInheritObject;
|
||||
float mInheritChance;
|
||||
float mVelocityMult;
|
||||
float mVelcoityVariation;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysBombModifier : public NiPSysModifier
|
||||
{
|
||||
NiNodePtr mBombObj;
|
||||
osg::Vec3f mBombAxis;
|
||||
float mDecay;
|
||||
float mDeltaV;
|
||||
|
||||
unsigned int mDecayType;
|
||||
unsigned int mSymmetryType;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiPSysDragModifier : public NiPSysModifier
|
||||
{
|
||||
NamedPtr mDragObj;
|
||||
osg::Vec3f mDragAxis;
|
||||
float mPercentage;
|
||||
float mRange;
|
||||
float mRangeFalloff;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -170,11 +170,30 @@ namespace Nif
|
|||
RC_BSMultiBoundSphere,
|
||||
RC_BSInvMarker,
|
||||
RC_BSTriShape,
|
||||
RC_NiPSysData,
|
||||
RC_BSEffectShaderPropertyFloatController,
|
||||
RC_BSEffectShaderPropertyColorController,
|
||||
RC_BSLightingShaderPropertyFloatController,
|
||||
RC_BSLightingShaderPropertyColorController,
|
||||
RC_BSBehaviorGraphExtraData,
|
||||
RC_NiParticleSystem,
|
||||
RC_NiPSysEmitterCtlr,
|
||||
RC_Controller,
|
||||
RC_NiPSysAgeDeathModifier,
|
||||
RC_BSPSysLODModifier,
|
||||
RC_NiPSysCylinderEmitter,
|
||||
RC_NiPSysSpawnModifier,
|
||||
RC_BSPSysSimpleColorModifier,
|
||||
RC_NiPSysRotationModifier,
|
||||
RC_BSPSysScaleModifier,
|
||||
RC_NiPSysGravityModifier,
|
||||
RC_NiPSysBoundUpdateModifier,
|
||||
RC_NiPSysModifier,
|
||||
RC_NiPSysModifierActiveCtlr,
|
||||
RC_NiPSysMeshEmitter,
|
||||
RC_BSPSysInheritVelocityModifier,
|
||||
RC_NiPSysBombModifier,
|
||||
RC_NiPSysDragModifier,
|
||||
};
|
||||
|
||||
/// Base class for all records
|
||||
|
|
|
@ -149,7 +149,13 @@ namespace Nif
|
|||
struct bhkCompressedMeshShapeData;
|
||||
struct BSMultiBound;
|
||||
struct BSMultiBoundData;
|
||||
struct NiPSysData;
|
||||
struct NiParticleSystem;
|
||||
struct NiPSysModifier;
|
||||
struct NiPSysSpawnModifier;
|
||||
struct NiNode;
|
||||
|
||||
using RecordPtr = RecordPtrT<Record>;
|
||||
using NodePtr = RecordPtrT<Node>;
|
||||
using ExtraPtr = RecordPtrT<Extra>;
|
||||
using NiUVDataPtr = RecordPtrT<NiUVData>;
|
||||
|
@ -187,6 +193,11 @@ namespace Nif
|
|||
using bhkCompressedMeshShapeDataPtr = RecordPtrT<bhkCompressedMeshShapeData>;
|
||||
using BSMultiBoundPtr = RecordPtrT<BSMultiBound>;
|
||||
using BSMultiBoundDataPtr = RecordPtrT<BSMultiBoundData>;
|
||||
using NiPSysDataPtr = RecordPtrT<NiPSysData>;
|
||||
using NiParticleSystemPtr = RecordPtrT<NiParticleSystem>;
|
||||
using NiPSysModifierPtr = RecordPtrT<NiPSysModifier>;
|
||||
using NiPSysSpawnModifierPtr = RecordPtrT<NiPSysSpawnModifier>;
|
||||
using NiNodePtr = RecordPtrT<NiNode>;
|
||||
|
||||
using NodeList = RecordListT<Node>;
|
||||
using PropertyList = RecordListT<Property>;
|
||||
|
|
|
@ -79,14 +79,14 @@ namespace
|
|||
|
||||
template <class Function>
|
||||
auto handleNiGeometry(const Nif::NiGeometry& geometry, Function&& function)
|
||||
-> decltype(function(static_cast<const Nif::NiTriShapeData&>(geometry.data.get())))
|
||||
-> decltype(function(static_cast<const Nif::NiTriShapeData&>(geometry.mData.get())))
|
||||
{
|
||||
if (geometry.recType == Nif::RC_NiTriShape || geometry.recType == Nif::RC_BSLODTriShape)
|
||||
{
|
||||
if (geometry.data->recType != Nif::RC_NiTriShapeData)
|
||||
if (geometry.mData->recType != Nif::RC_NiTriShapeData)
|
||||
return {};
|
||||
|
||||
auto data = static_cast<const Nif::NiTriShapeData*>(geometry.data.getPtr());
|
||||
auto data = static_cast<const Nif::NiTriShapeData*>(geometry.mData.getPtr());
|
||||
if (data->triangles.empty())
|
||||
return {};
|
||||
|
||||
|
@ -95,10 +95,10 @@ namespace
|
|||
|
||||
if (geometry.recType == Nif::RC_NiTriStrips)
|
||||
{
|
||||
if (geometry.data->recType != Nif::RC_NiTriStripsData)
|
||||
if (geometry.mData->recType != Nif::RC_NiTriStripsData)
|
||||
return {};
|
||||
|
||||
auto data = static_cast<const Nif::NiTriStripsData*>(geometry.data.getPtr());
|
||||
auto data = static_cast<const Nif::NiTriStripsData*>(geometry.mData.getPtr());
|
||||
if (data->strips.empty())
|
||||
return {};
|
||||
|
||||
|
@ -380,10 +380,10 @@ namespace NifBullet
|
|||
if (args.mHasMarkers && Misc::StringUtils::ciStartsWith(niGeometry.name, "EditorMarker"))
|
||||
return;
|
||||
|
||||
if (niGeometry.data.empty() || niGeometry.data->vertices.empty())
|
||||
if (niGeometry.mData.empty() || niGeometry.mData->vertices.empty())
|
||||
return;
|
||||
|
||||
if (!niGeometry.skin.empty())
|
||||
if (!niGeometry.mSkinInstance.empty())
|
||||
args.mAnimated = false;
|
||||
// TODO: handle NiSkinPartition
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include "nifloader.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <components/nif/record.hpp>
|
||||
#include <mutex>
|
||||
#include <osg/Vec3>
|
||||
#include <string_view>
|
||||
|
||||
#include <osg/Array>
|
||||
|
@ -48,6 +51,7 @@
|
|||
#include <components/nif/extra.hpp>
|
||||
#include <components/nif/niffile.hpp>
|
||||
#include <components/nif/node.hpp>
|
||||
#include <components/nif/particle.hpp>
|
||||
#include <components/nif/property.hpp>
|
||||
#include <components/sceneutil/depth.hpp>
|
||||
#include <components/sceneutil/morphgeometry.hpp>
|
||||
|
@ -127,10 +131,10 @@ namespace
|
|||
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
||||
if (geometry)
|
||||
{
|
||||
if (!geometry->shaderprop.empty())
|
||||
out.emplace_back(geometry->shaderprop.getPtr());
|
||||
if (!geometry->alphaprop.empty())
|
||||
out.emplace_back(geometry->alphaprop.getPtr());
|
||||
if (!geometry->mShaderProperty.empty())
|
||||
out.emplace_back(geometry->mShaderProperty.getPtr());
|
||||
if (!geometry->mAlphaProperty.empty())
|
||||
out.emplace_back(geometry->mAlphaProperty.getPtr());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,8 +440,8 @@ namespace NifOsg
|
|||
|
||||
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
||||
// NiGeometry's NiAlphaProperty doesn't get handled here because it's a drawable property
|
||||
if (geometry && !geometry->shaderprop.empty())
|
||||
handleProperty(geometry->shaderprop.getPtr(), applyTo, composite, imageManager, boundTextures,
|
||||
if (geometry && !geometry->mShaderProperty.empty())
|
||||
handleProperty(geometry->mShaderProperty.getPtr(), applyTo, composite, imageManager, boundTextures,
|
||||
animflags, hasStencilProperty);
|
||||
}
|
||||
|
||||
|
@ -759,7 +763,7 @@ namespace NifOsg
|
|||
skip = args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->name, "EditorMarker");
|
||||
if (!skip)
|
||||
{
|
||||
Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->skin;
|
||||
Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->mSkinInstance;
|
||||
|
||||
if (skin.empty())
|
||||
handleGeometry(nifNode, parent, node, composite, args.mBoundTextures, args.mAnimFlags);
|
||||
|
@ -1120,13 +1124,13 @@ namespace NifOsg
|
|||
const Nif::Node* nifNode, ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl)
|
||||
{
|
||||
auto particleNode = static_cast<const Nif::NiParticles*>(nifNode);
|
||||
if (particleNode->data.empty() || particleNode->data->recType != Nif::RC_NiParticlesData)
|
||||
if (particleNode->mData.empty() || particleNode->mData->recType != Nif::RC_NiParticlesData)
|
||||
{
|
||||
partsys->setQuota(partctrl->numParticles);
|
||||
return;
|
||||
}
|
||||
|
||||
auto particledata = static_cast<const Nif::NiParticlesData*>(particleNode->data.getPtr());
|
||||
auto particledata = static_cast<const Nif::NiParticlesData*>(particleNode->mData.getPtr());
|
||||
partsys->setQuota(particledata->numParticles);
|
||||
|
||||
osg::BoundingBox box;
|
||||
|
@ -1376,13 +1380,13 @@ namespace NifOsg
|
|||
const std::vector<unsigned int>& boundTextures, int animflags)
|
||||
{
|
||||
const Nif::NiGeometry* niGeometry = static_cast<const Nif::NiGeometry*>(nifNode);
|
||||
if (niGeometry->data.empty())
|
||||
if (niGeometry->mData.empty())
|
||||
return;
|
||||
|
||||
bool hasPartitions = false;
|
||||
if (!niGeometry->skin.empty())
|
||||
if (!niGeometry->mSkinInstance.empty())
|
||||
{
|
||||
const Nif::NiSkinInstance* skin = niGeometry->skin.getPtr();
|
||||
const Nif::NiSkinInstance* skin = niGeometry->mSkinInstance.getPtr();
|
||||
const Nif::NiSkinData* data = nullptr;
|
||||
const Nif::NiSkinPartition* partitions = nullptr;
|
||||
if (!skin->data.empty())
|
||||
|
@ -1416,7 +1420,7 @@ namespace NifOsg
|
|||
}
|
||||
}
|
||||
|
||||
const Nif::NiGeometryData* niGeometryData = niGeometry->data.getPtr();
|
||||
const Nif::NiGeometryData* niGeometryData = niGeometry->mData.getPtr();
|
||||
if (!hasPartitions)
|
||||
{
|
||||
if (niGeometry->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_BSLODTriShape)
|
||||
|
@ -1542,7 +1546,7 @@ namespace NifOsg
|
|||
// Assign bone weights
|
||||
osg::ref_ptr<SceneUtil::RigGeometry::InfluenceMap> map(new SceneUtil::RigGeometry::InfluenceMap);
|
||||
|
||||
const Nif::NiSkinInstance* skin = static_cast<const Nif::NiGeometry*>(nifNode)->skin.getPtr();
|
||||
const Nif::NiSkinInstance* skin = static_cast<const Nif::NiGeometry*>(nifNode)->mSkinInstance.getPtr();
|
||||
const Nif::NiSkinData* data = skin->data.getPtr();
|
||||
const Nif::NodeList& bones = skin->bones;
|
||||
for (std::size_t i = 0, n = bones.size(); i < n; ++i)
|
||||
|
@ -2676,5 +2680,4 @@ namespace NifOsg
|
|||
LoaderImpl impl(kf.getFilename(), kf.getVersion(), kf.getUserVersion(), kf.getBethVersion());
|
||||
impl.loadKf(kf, target);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue