mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-27 03:40:24 +00:00
Merge branch 'loadSSEAlchemyTable' into 'master'
Load SSE alchemy table See merge request OpenMW/openmw!3267
This commit is contained in:
commit
81deb3796b
16 changed files with 952 additions and 136 deletions
|
@ -35,8 +35,8 @@ namespace Nif::Testing
|
||||||
inline void init(NiGeometry& value)
|
inline void init(NiGeometry& value)
|
||||||
{
|
{
|
||||||
init(static_cast<Node&>(value));
|
init(static_cast<Node&>(value));
|
||||||
value.data = NiGeometryDataPtr(nullptr);
|
value.mData = NiGeometryDataPtr(nullptr);
|
||||||
value.skin = NiSkinInstancePtr(nullptr);
|
value.mSkinInstance = NiSkinInstancePtr(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void init(NiTriShape& value)
|
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.vertices = { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0) };
|
||||||
mNiTriShapeData.mNumTriangles = 1;
|
mNiTriShapeData.mNumTriangles = 1;
|
||||||
mNiTriShapeData.triangles = { 0, 1, 2 };
|
mNiTriShapeData.triangles = { 0, 1, 2 };
|
||||||
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
mNiTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||||
|
|
||||||
mNiTriShapeData2.recType = Nif::RC_NiTriShapeData;
|
mNiTriShapeData2.recType = Nif::RC_NiTriShapeData;
|
||||||
mNiTriShapeData2.vertices = { osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1) };
|
mNiTriShapeData2.vertices = { osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1) };
|
||||||
mNiTriShapeData2.mNumTriangles = 1;
|
mNiTriShapeData2.mNumTriangles = 1;
|
||||||
mNiTriShapeData2.triangles = { 0, 1, 2 };
|
mNiTriShapeData2.triangles = { 0, 1, 2 };
|
||||||
mNiTriShape2.data = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
mNiTriShape2.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
||||||
|
|
||||||
mNiTriStripsData.recType = Nif::RC_NiTriStripsData;
|
mNiTriStripsData.recType = Nif::RC_NiTriStripsData;
|
||||||
mNiTriStripsData.vertices
|
mNiTriStripsData.vertices
|
||||||
= { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0), osg::Vec3f(0, 1, 0) };
|
= { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0), osg::Vec3f(0, 1, 0) };
|
||||||
mNiTriStripsData.mNumTriangles = 2;
|
mNiTriStripsData.mNumTriangles = 2;
|
||||||
mNiTriStripsData.strips = { { 0, 1, 2, 3 } };
|
mNiTriStripsData.strips = { { 0, 1, 2, 3 } };
|
||||||
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
mNiTriStrips.mData = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -716,7 +716,7 @@ namespace
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(TestBulletNifLoader,
|
||||||
for_tri_shape_child_node_and_filename_starting_with_x_and_not_empty_skin_should_return_static_shape)
|
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);
|
mNiTriShape.parents.push_back(&mNiNode);
|
||||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
|
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)
|
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);
|
mNiTriShape.parents.push_back(&mNiNode);
|
||||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
|
||||||
|
|
||||||
|
@ -977,7 +977,7 @@ namespace
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(TestBulletNifLoader,
|
||||||
for_tri_shape_child_node_with_empty_data_triangles_should_return_shape_with_null_collision_shape)
|
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();
|
data->triangles.clear();
|
||||||
mNiTriShape.parents.push_back(&mNiNode);
|
mNiTriShape.parents.push_back(&mNiNode);
|
||||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
|
||||||
|
@ -1111,7 +1111,7 @@ namespace
|
||||||
init(niTriShape);
|
init(niTriShape);
|
||||||
init(emptyCollisionNode);
|
init(emptyCollisionNode);
|
||||||
|
|
||||||
niTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
niTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||||
niTriShape.parents.push_back(&mNiNode);
|
niTriShape.parents.push_back(&mNiNode);
|
||||||
|
|
||||||
emptyCollisionNode.recType = Nif::RC_RootCollisionNode;
|
emptyCollisionNode.recType = Nif::RC_RootCollisionNode;
|
||||||
|
@ -1210,7 +1210,7 @@ namespace
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, should_ignore_tri_shape_data_with_mismatching_data_rec_type)
|
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");
|
Nif::NIFFile file("test.nif");
|
||||||
file.mRoots.push_back(&mNiTriShape);
|
file.mRoots.push_back(&mNiTriShape);
|
||||||
|
@ -1245,7 +1245,7 @@ namespace
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, should_ignore_tri_strips_data_with_mismatching_data_rec_type)
|
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");
|
Nif::NIFFile file("test.nif");
|
||||||
file.mRoots.push_back(&mNiTriStrips);
|
file.mRoots.push_back(&mNiTriStrips);
|
||||||
|
|
|
@ -103,7 +103,7 @@ add_component_dir (sceneutil
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (nif
|
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
|
add_component_dir (nifosg
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "controlled.hpp"
|
#include "controlled.hpp"
|
||||||
#include "data.hpp"
|
#include "data.hpp"
|
||||||
#include "node.hpp"
|
#include "node.hpp"
|
||||||
|
#include "particle.hpp"
|
||||||
#include "recordptr.hpp"
|
#include "recordptr.hpp"
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
|
|
|
@ -46,29 +46,47 @@ namespace Nif
|
||||||
|
|
||||||
void NiGeometryData::read(NIFStream* 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))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 114))
|
||||||
nif->getInt(); // Group ID. (Almost?) always 0.
|
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))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||||
nif->skip(2); // Keep flags and compress flags
|
nif->skip(2); // Keep flags and compress flags
|
||||||
|
|
||||||
if (nif->getBoolean())
|
bool hasVertices = true;
|
||||||
|
hasVertices = nif->getBoolean();
|
||||||
|
if (hasVertices)
|
||||||
nif->getVector3s(vertices, verts);
|
nif->getVector3s(vertices, verts);
|
||||||
|
|
||||||
unsigned int dataFlags = 0;
|
unsigned short NiDataFlags = 0, BSDataFlags = 0;
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0) && !isBS202)
|
||||||
dataFlags = nif->getUShort();
|
nif->read(NiDataFlags);
|
||||||
|
if (isBS202)
|
||||||
|
nif->read(BSDataFlags);
|
||||||
|
|
||||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS
|
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS
|
||||||
&& nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
&& nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
||||||
nif->getUInt(); // Material CRC
|
nif->getUInt(); // Material CRC
|
||||||
|
|
||||||
if (nif->getBoolean())
|
bool hasNormals;
|
||||||
|
hasNormals = nif->getBoolean();
|
||||||
|
if (hasNormals)
|
||||||
{
|
{
|
||||||
nif->getVector3s(normals, verts);
|
nif->getVector3s(normals, verts);
|
||||||
if (dataFlags & 0x1000)
|
if ((NiDataFlags | BSDataFlags) & 0x1000)
|
||||||
{
|
{
|
||||||
nif->getVector3s(tangents, verts);
|
nif->getVector3s(tangents, verts);
|
||||||
nif->getVector3s(bitangents, verts);
|
nif->getVector3s(bitangents, verts);
|
||||||
|
@ -78,41 +96,36 @@ namespace Nif
|
||||||
center = nif->getVector3();
|
center = nif->getVector3();
|
||||||
radius = nif->getFloat();
|
radius = nif->getFloat();
|
||||||
|
|
||||||
if (nif->getBoolean())
|
bool hasVertexColors;
|
||||||
|
hasVertexColors = nif->getBoolean();
|
||||||
|
if (hasVertexColors)
|
||||||
nif->getVector4s(colors, verts);
|
nif->getVector4s(colors, verts);
|
||||||
|
|
||||||
unsigned int numUVs = dataFlags;
|
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0))
|
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 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.
|
// 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)
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW)
|
||||||
hasUVs = nif->getBoolean();
|
// nif->read(hasUVs);
|
||||||
if (hasUVs)
|
nif->getBoolean(); // hasUVs
|
||||||
|
|
||||||
|
uvlist.resize(numUVs);
|
||||||
|
for (unsigned int i = 0; i < numUVs; i++)
|
||||||
{
|
{
|
||||||
uvlist.resize(numUVs);
|
nif->getVector2s(uvlist[i], verts);
|
||||||
for (unsigned int i = 0; i < numUVs; i++)
|
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
|
// 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)
|
uv = osg::Vec2f(uv.x(), 1.f - uv.y());
|
||||||
{
|
|
||||||
uvlist[i][uv] = osg::Vec2f(uvlist[i][uv].x(), 1.f - uvlist[i][uv].y());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned short consistencyFlag;
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0))
|
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))
|
if (nif->getVersion() >= NIFStream::generateVersion(20, 0, 0, 4))
|
||||||
nif->skip(4); // Additional data
|
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)
|
void NiPosData::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
mKeyList = std::make_shared<Vector3KeyMap>();
|
mKeyList = std::make_shared<Vector3KeyMap>();
|
||||||
|
@ -561,5 +537,4 @@ namespace Nif
|
||||||
mCenter = nif->getVector3();
|
mCenter = nif->getVector3();
|
||||||
mRadius = nif->getFloat();
|
mRadius = nif->getFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "nifkey.hpp"
|
#include "nifkey.hpp"
|
||||||
#include "niftypes.hpp" // Transformation
|
#include "niftypes.hpp" // Transformation
|
||||||
#include "recordptr.hpp"
|
#include "recordptr.hpp"
|
||||||
|
#include <components/nif/controller.hpp>
|
||||||
#include <components/nif/node.hpp>
|
#include <components/nif/node.hpp>
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
|
@ -41,6 +42,8 @@ namespace Nif
|
||||||
osg::Vec3f center;
|
osg::Vec3f center;
|
||||||
float radius;
|
float radius;
|
||||||
|
|
||||||
|
bool NiPSysDataFlag = false;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,24 +79,6 @@ namespace Nif
|
||||||
void read(NIFStream* nif) override;
|
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
|
struct NiPosData : public Record
|
||||||
{
|
{
|
||||||
Vector3KeyMapPtr mKeyList;
|
Vector3KeyMapPtr mKeyList;
|
||||||
|
@ -329,6 +314,5 @@ namespace Nif
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "extra.hpp"
|
#include "extra.hpp"
|
||||||
#include "node.hpp"
|
#include "node.hpp"
|
||||||
|
#include "particle.hpp"
|
||||||
#include "physics.hpp"
|
#include "physics.hpp"
|
||||||
#include "property.hpp"
|
#include "property.hpp"
|
||||||
|
|
||||||
|
@ -217,6 +218,26 @@ namespace Nif
|
||||||
{ "BSLightingShaderPropertyColorController",
|
{ "BSLightingShaderPropertyColorController",
|
||||||
&construct<BSEffectShaderPropertyColorController, RC_BSLightingShaderPropertyColorController> },
|
&construct<BSEffectShaderPropertyColorController, RC_BSLightingShaderPropertyColorController> },
|
||||||
{ "BSBehaviorGraphExtraData", &construct<BSBehaviorGraphExtraData, RC_BSBehaviorGraphExtraData> },
|
{ "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);
|
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::Vec3f& data) { readLittleEndianBufferOfType<3, float>(inp, data._v); }
|
||||||
void read(osg::Vec4f& data) { readLittleEndianBufferOfType<4, 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)
|
void NiGeometry::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
Node::read(nif);
|
Node::read(nif);
|
||||||
data.read(nif);
|
|
||||||
skin.read(nif);
|
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && NiParticleSystemFlag)
|
||||||
material.read(nif);
|
{
|
||||||
|
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
|
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS
|
||||||
&& nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
&& nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
||||||
{
|
{
|
||||||
shaderprop.read(nif);
|
mShaderProperty.read(nif);
|
||||||
alphaprop.read(nif);
|
mAlphaProperty.read(nif);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiGeometry::post(Reader& nif)
|
void NiGeometry::post(Reader& nif)
|
||||||
{
|
{
|
||||||
Node::post(nif);
|
Node::post(nif);
|
||||||
data.post(nif);
|
mData.post(nif);
|
||||||
skin.post(nif);
|
mSkin.post(nif);
|
||||||
shaderprop.post(nif);
|
mSkinInstance.post(nif);
|
||||||
alphaprop.post(nif);
|
mShaderProperty.post(nif);
|
||||||
if (recType != RC_NiParticles && !skin.empty())
|
mAlphaProperty.post(nif);
|
||||||
|
if (recType != RC_NiParticles && !mSkinInstance.empty())
|
||||||
nif.setUseSkinning(true);
|
nif.setUseSkinning(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +410,9 @@ namespace Nif
|
||||||
nif->read(mParticleDataSize);
|
nif->read(mParticleDataSize);
|
||||||
if (mParticleDataSize > 0)
|
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
|
#define OPENMW_COMPONENTS_NIF_NODE_HPP
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <components/nif/recordptr.hpp>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <osg/Plane>
|
#include <osg/Plane>
|
||||||
|
@ -151,11 +152,17 @@ namespace Nif
|
||||||
void read(NIFStream* nif);
|
void read(NIFStream* nif);
|
||||||
};
|
};
|
||||||
|
|
||||||
NiGeometryDataPtr data;
|
NiGeometryDataPtr mData;
|
||||||
NiSkinInstancePtr skin;
|
NiSkinInstancePtr mSkinInstance;
|
||||||
|
RecordPtr mSkin;
|
||||||
MaterialData material;
|
MaterialData material;
|
||||||
BSShaderPropertyPtr shaderprop;
|
BSShaderPropertyPtr mShaderProperty;
|
||||||
NiAlphaPropertyPtr alphaprop;
|
NiAlphaPropertyPtr mAlphaProperty;
|
||||||
|
|
||||||
|
NiBoundingVolume::NiSphereBV mBoundingVolume;
|
||||||
|
float mBoundMinMax;
|
||||||
|
|
||||||
|
bool NiParticleSystemFlag = false;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
void post(Reader& nif) override;
|
void post(Reader& nif) override;
|
||||||
|
@ -175,9 +182,6 @@ namespace Nif
|
||||||
struct NiLines : NiGeometry
|
struct NiLines : NiGeometry
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
struct NiParticles : NiGeometry
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NiCamera : Node
|
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_BSMultiBoundSphere,
|
||||||
RC_BSInvMarker,
|
RC_BSInvMarker,
|
||||||
RC_BSTriShape,
|
RC_BSTriShape,
|
||||||
|
RC_NiPSysData,
|
||||||
RC_BSEffectShaderPropertyFloatController,
|
RC_BSEffectShaderPropertyFloatController,
|
||||||
RC_BSEffectShaderPropertyColorController,
|
RC_BSEffectShaderPropertyColorController,
|
||||||
RC_BSLightingShaderPropertyFloatController,
|
RC_BSLightingShaderPropertyFloatController,
|
||||||
RC_BSLightingShaderPropertyColorController,
|
RC_BSLightingShaderPropertyColorController,
|
||||||
RC_BSBehaviorGraphExtraData,
|
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
|
/// Base class for all records
|
||||||
|
|
|
@ -149,7 +149,13 @@ namespace Nif
|
||||||
struct bhkCompressedMeshShapeData;
|
struct bhkCompressedMeshShapeData;
|
||||||
struct BSMultiBound;
|
struct BSMultiBound;
|
||||||
struct BSMultiBoundData;
|
struct BSMultiBoundData;
|
||||||
|
struct NiPSysData;
|
||||||
|
struct NiParticleSystem;
|
||||||
|
struct NiPSysModifier;
|
||||||
|
struct NiPSysSpawnModifier;
|
||||||
|
struct NiNode;
|
||||||
|
|
||||||
|
using RecordPtr = RecordPtrT<Record>;
|
||||||
using NodePtr = RecordPtrT<Node>;
|
using NodePtr = RecordPtrT<Node>;
|
||||||
using ExtraPtr = RecordPtrT<Extra>;
|
using ExtraPtr = RecordPtrT<Extra>;
|
||||||
using NiUVDataPtr = RecordPtrT<NiUVData>;
|
using NiUVDataPtr = RecordPtrT<NiUVData>;
|
||||||
|
@ -187,6 +193,11 @@ namespace Nif
|
||||||
using bhkCompressedMeshShapeDataPtr = RecordPtrT<bhkCompressedMeshShapeData>;
|
using bhkCompressedMeshShapeDataPtr = RecordPtrT<bhkCompressedMeshShapeData>;
|
||||||
using BSMultiBoundPtr = RecordPtrT<BSMultiBound>;
|
using BSMultiBoundPtr = RecordPtrT<BSMultiBound>;
|
||||||
using BSMultiBoundDataPtr = RecordPtrT<BSMultiBoundData>;
|
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 NodeList = RecordListT<Node>;
|
||||||
using PropertyList = RecordListT<Property>;
|
using PropertyList = RecordListT<Property>;
|
||||||
|
|
|
@ -79,14 +79,14 @@ namespace
|
||||||
|
|
||||||
template <class Function>
|
template <class Function>
|
||||||
auto handleNiGeometry(const Nif::NiGeometry& geometry, Function&& 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.recType == Nif::RC_NiTriShape || geometry.recType == Nif::RC_BSLODTriShape)
|
||||||
{
|
{
|
||||||
if (geometry.data->recType != Nif::RC_NiTriShapeData)
|
if (geometry.mData->recType != Nif::RC_NiTriShapeData)
|
||||||
return {};
|
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())
|
if (data->triangles.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -95,10 +95,10 @@ namespace
|
||||||
|
|
||||||
if (geometry.recType == Nif::RC_NiTriStrips)
|
if (geometry.recType == Nif::RC_NiTriStrips)
|
||||||
{
|
{
|
||||||
if (geometry.data->recType != Nif::RC_NiTriStripsData)
|
if (geometry.mData->recType != Nif::RC_NiTriStripsData)
|
||||||
return {};
|
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())
|
if (data->strips.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -380,10 +380,10 @@ namespace NifBullet
|
||||||
if (args.mHasMarkers && Misc::StringUtils::ciStartsWith(niGeometry.name, "EditorMarker"))
|
if (args.mHasMarkers && Misc::StringUtils::ciStartsWith(niGeometry.name, "EditorMarker"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (niGeometry.data.empty() || niGeometry.data->vertices.empty())
|
if (niGeometry.mData.empty() || niGeometry.mData->vertices.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!niGeometry.skin.empty())
|
if (!niGeometry.mSkinInstance.empty())
|
||||||
args.mAnimated = false;
|
args.mAnimated = false;
|
||||||
// TODO: handle NiSkinPartition
|
// TODO: handle NiSkinPartition
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "nifloader.hpp"
|
#include "nifloader.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <components/nif/record.hpp>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <osg/Vec3>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include <osg/Array>
|
#include <osg/Array>
|
||||||
|
@ -48,6 +51,7 @@
|
||||||
#include <components/nif/extra.hpp>
|
#include <components/nif/extra.hpp>
|
||||||
#include <components/nif/niffile.hpp>
|
#include <components/nif/niffile.hpp>
|
||||||
#include <components/nif/node.hpp>
|
#include <components/nif/node.hpp>
|
||||||
|
#include <components/nif/particle.hpp>
|
||||||
#include <components/nif/property.hpp>
|
#include <components/nif/property.hpp>
|
||||||
#include <components/sceneutil/depth.hpp>
|
#include <components/sceneutil/depth.hpp>
|
||||||
#include <components/sceneutil/morphgeometry.hpp>
|
#include <components/sceneutil/morphgeometry.hpp>
|
||||||
|
@ -127,10 +131,10 @@ namespace
|
||||||
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
||||||
if (geometry)
|
if (geometry)
|
||||||
{
|
{
|
||||||
if (!geometry->shaderprop.empty())
|
if (!geometry->mShaderProperty.empty())
|
||||||
out.emplace_back(geometry->shaderprop.getPtr());
|
out.emplace_back(geometry->mShaderProperty.getPtr());
|
||||||
if (!geometry->alphaprop.empty())
|
if (!geometry->mAlphaProperty.empty())
|
||||||
out.emplace_back(geometry->alphaprop.getPtr());
|
out.emplace_back(geometry->mAlphaProperty.getPtr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,8 +440,8 @@ namespace NifOsg
|
||||||
|
|
||||||
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
||||||
// NiGeometry's NiAlphaProperty doesn't get handled here because it's a drawable property
|
// NiGeometry's NiAlphaProperty doesn't get handled here because it's a drawable property
|
||||||
if (geometry && !geometry->shaderprop.empty())
|
if (geometry && !geometry->mShaderProperty.empty())
|
||||||
handleProperty(geometry->shaderprop.getPtr(), applyTo, composite, imageManager, boundTextures,
|
handleProperty(geometry->mShaderProperty.getPtr(), applyTo, composite, imageManager, boundTextures,
|
||||||
animflags, hasStencilProperty);
|
animflags, hasStencilProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,7 +763,7 @@ namespace NifOsg
|
||||||
skip = args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->name, "EditorMarker");
|
skip = args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->name, "EditorMarker");
|
||||||
if (!skip)
|
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())
|
if (skin.empty())
|
||||||
handleGeometry(nifNode, parent, node, composite, args.mBoundTextures, args.mAnimFlags);
|
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)
|
const Nif::Node* nifNode, ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl)
|
||||||
{
|
{
|
||||||
auto particleNode = static_cast<const Nif::NiParticles*>(nifNode);
|
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);
|
partsys->setQuota(partctrl->numParticles);
|
||||||
return;
|
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);
|
partsys->setQuota(particledata->numParticles);
|
||||||
|
|
||||||
osg::BoundingBox box;
|
osg::BoundingBox box;
|
||||||
|
@ -1376,13 +1380,13 @@ namespace NifOsg
|
||||||
const std::vector<unsigned int>& boundTextures, int animflags)
|
const std::vector<unsigned int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
const Nif::NiGeometry* niGeometry = static_cast<const Nif::NiGeometry*>(nifNode);
|
const Nif::NiGeometry* niGeometry = static_cast<const Nif::NiGeometry*>(nifNode);
|
||||||
if (niGeometry->data.empty())
|
if (niGeometry->mData.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool hasPartitions = false;
|
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::NiSkinData* data = nullptr;
|
||||||
const Nif::NiSkinPartition* partitions = nullptr;
|
const Nif::NiSkinPartition* partitions = nullptr;
|
||||||
if (!skin->data.empty())
|
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 (!hasPartitions)
|
||||||
{
|
{
|
||||||
if (niGeometry->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_BSLODTriShape)
|
if (niGeometry->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_BSLODTriShape)
|
||||||
|
@ -1542,7 +1546,7 @@ namespace NifOsg
|
||||||
// Assign bone weights
|
// Assign bone weights
|
||||||
osg::ref_ptr<SceneUtil::RigGeometry::InfluenceMap> map(new SceneUtil::RigGeometry::InfluenceMap);
|
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::NiSkinData* data = skin->data.getPtr();
|
||||||
const Nif::NodeList& bones = skin->bones;
|
const Nif::NodeList& bones = skin->bones;
|
||||||
for (std::size_t i = 0, n = bones.size(); i < n; ++i)
|
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());
|
LoaderImpl impl(kf.getFilename(), kf.getVersion(), kf.getUserVersion(), kf.getBethVersion());
|
||||||
impl.loadKf(kf, target);
|
impl.loadKf(kf, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue