mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-19 20:53:52 +00:00
Merge branch 'alsonif' into 'master'
Modernize NIF loader, part V: Skyrim See merge request OpenMW/openmw!3428
This commit is contained in:
commit
9333840bb1
6 changed files with 343 additions and 351 deletions
|
@ -33,8 +33,8 @@ namespace Nif::Testing
|
||||||
inline void init(NiGeometry& value)
|
inline void init(NiGeometry& value)
|
||||||
{
|
{
|
||||||
init(static_cast<NiAVObject&>(value));
|
init(static_cast<NiAVObject&>(value));
|
||||||
value.data = NiGeometryDataPtr(nullptr);
|
value.mData = NiGeometryDataPtr(nullptr);
|
||||||
value.skin = NiSkinInstancePtr(nullptr);
|
value.mSkin = NiSkinInstancePtr(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void init(NiTriShape& value)
|
inline void init(NiTriShape& value)
|
||||||
|
|
|
@ -326,20 +326,20 @@ namespace
|
||||||
mNiTriShapeData.mVertices = { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0) };
|
mNiTriShapeData.mVertices = { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0) };
|
||||||
mNiTriShapeData.mNumTriangles = 1;
|
mNiTriShapeData.mNumTriangles = 1;
|
||||||
mNiTriShapeData.mTriangles = { 0, 1, 2 };
|
mNiTriShapeData.mTriangles = { 0, 1, 2 };
|
||||||
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
mNiTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||||
|
|
||||||
mNiTriShapeData2.recType = Nif::RC_NiTriShapeData;
|
mNiTriShapeData2.recType = Nif::RC_NiTriShapeData;
|
||||||
mNiTriShapeData2.mVertices = { osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1) };
|
mNiTriShapeData2.mVertices = { osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1) };
|
||||||
mNiTriShapeData2.mNumTriangles = 1;
|
mNiTriShapeData2.mNumTriangles = 1;
|
||||||
mNiTriShapeData2.mTriangles = { 0, 1, 2 };
|
mNiTriShapeData2.mTriangles = { 0, 1, 2 };
|
||||||
mNiTriShape2.data = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
mNiTriShape2.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
||||||
|
|
||||||
mNiTriStripsData.recType = Nif::RC_NiTriStripsData;
|
mNiTriStripsData.recType = Nif::RC_NiTriStripsData;
|
||||||
mNiTriStripsData.mVertices
|
mNiTriStripsData.mVertices
|
||||||
= { 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.mStrips = { { 0, 1, 2, 3 } };
|
mNiTriStripsData.mStrips = { { 0, 1, 2, 3 } };
|
||||||
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
mNiTriStrips.mData = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -415,9 +415,9 @@ namespace
|
||||||
TestBulletNifLoader, for_root_nif_node_with_bounding_box_should_return_shape_with_compound_shape_and_box_inside)
|
TestBulletNifLoader, for_root_nif_node_with_bounding_box_should_return_shape_with_compound_shape_and_box_inside)
|
||||||
{
|
{
|
||||||
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
||||||
mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3);
|
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
|
||||||
mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3);
|
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
Nif::NIFFile file("test.nif");
|
Nif::NIFFile file("test.nif");
|
||||||
file.mRoots.push_back(&mNode);
|
file.mRoots.push_back(&mNode);
|
||||||
|
@ -439,9 +439,9 @@ namespace
|
||||||
TEST_F(TestBulletNifLoader, for_child_nif_node_with_bounding_box)
|
TEST_F(TestBulletNifLoader, for_child_nif_node_with_bounding_box)
|
||||||
{
|
{
|
||||||
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
||||||
mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3);
|
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
|
||||||
mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3);
|
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
|
||||||
mNode.mParents.push_back(&mNiNode);
|
mNode.mParents.push_back(&mNiNode);
|
||||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode) };
|
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode) };
|
||||||
|
|
||||||
|
@ -466,14 +466,14 @@ namespace
|
||||||
for_root_and_child_nif_node_with_bounding_box_but_root_without_flag_should_use_child_bounds)
|
for_root_and_child_nif_node_with_bounding_box_but_root_without_flag_should_use_child_bounds)
|
||||||
{
|
{
|
||||||
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
||||||
mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3);
|
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
|
||||||
mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3);
|
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
|
||||||
mNode.mParents.push_back(&mNiNode);
|
mNode.mParents.push_back(&mNiNode);
|
||||||
|
|
||||||
mNiNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNiNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNiNode.mBounds.box.extents = osg::Vec3f(4, 5, 6);
|
mNiNode.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6);
|
||||||
mNiNode.mBounds.box.center = osg::Vec3f(-4, -5, -6);
|
mNiNode.mBounds.mBox.mCenter = osg::Vec3f(-4, -5, -6);
|
||||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode) };
|
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode) };
|
||||||
|
|
||||||
Nif::NIFFile file("test.nif");
|
Nif::NIFFile file("test.nif");
|
||||||
|
@ -497,19 +497,19 @@ namespace
|
||||||
for_root_and_two_children_where_both_with_bounds_but_only_first_with_flag_should_use_first_bounds)
|
for_root_and_two_children_where_both_with_bounds_but_only_first_with_flag_should_use_first_bounds)
|
||||||
{
|
{
|
||||||
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
||||||
mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3);
|
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
|
||||||
mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3);
|
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
|
||||||
mNode.mParents.push_back(&mNiNode);
|
mNode.mParents.push_back(&mNiNode);
|
||||||
|
|
||||||
mNode2.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNode2.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNode2.mBounds.box.extents = osg::Vec3f(4, 5, 6);
|
mNode2.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6);
|
||||||
mNode2.mBounds.box.center = osg::Vec3f(-4, -5, -6);
|
mNode2.mBounds.mBox.mCenter = osg::Vec3f(-4, -5, -6);
|
||||||
mNode2.mParents.push_back(&mNiNode);
|
mNode2.mParents.push_back(&mNiNode);
|
||||||
|
|
||||||
mNiNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNiNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNiNode.mBounds.box.extents = osg::Vec3f(7, 8, 9);
|
mNiNode.mBounds.mBox.mExtents = osg::Vec3f(7, 8, 9);
|
||||||
mNiNode.mBounds.box.center = osg::Vec3f(-7, -8, -9);
|
mNiNode.mBounds.mBox.mCenter = osg::Vec3f(-7, -8, -9);
|
||||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode), Nif::NiAVObjectPtr(&mNode2) };
|
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode), Nif::NiAVObjectPtr(&mNode2) };
|
||||||
|
|
||||||
Nif::NIFFile file("test.nif");
|
Nif::NIFFile file("test.nif");
|
||||||
|
@ -532,20 +532,20 @@ namespace
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(TestBulletNifLoader,
|
||||||
for_root_and_two_children_where_both_with_bounds_but_only_second_with_flag_should_use_second_bounds)
|
for_root_and_two_children_where_both_with_bounds_but_only_second_with_flag_should_use_second_bounds)
|
||||||
{
|
{
|
||||||
mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3);
|
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
|
||||||
mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3);
|
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
|
||||||
mNode.mParents.push_back(&mNiNode);
|
mNode.mParents.push_back(&mNiNode);
|
||||||
|
|
||||||
mNode2.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
mNode2.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
||||||
mNode2.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNode2.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNode2.mBounds.box.extents = osg::Vec3f(4, 5, 6);
|
mNode2.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6);
|
||||||
mNode2.mBounds.box.center = osg::Vec3f(-4, -5, -6);
|
mNode2.mBounds.mBox.mCenter = osg::Vec3f(-4, -5, -6);
|
||||||
mNode2.mParents.push_back(&mNiNode);
|
mNode2.mParents.push_back(&mNiNode);
|
||||||
|
|
||||||
mNiNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNiNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNiNode.mBounds.box.extents = osg::Vec3f(7, 8, 9);
|
mNiNode.mBounds.mBox.mExtents = osg::Vec3f(7, 8, 9);
|
||||||
mNiNode.mBounds.box.center = osg::Vec3f(-7, -8, -9);
|
mNiNode.mBounds.mBox.mCenter = osg::Vec3f(-7, -8, -9);
|
||||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode), Nif::NiAVObjectPtr(&mNode2) };
|
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode), Nif::NiAVObjectPtr(&mNode2) };
|
||||||
|
|
||||||
Nif::NIFFile file("test.nif");
|
Nif::NIFFile file("test.nif");
|
||||||
|
@ -568,9 +568,9 @@ namespace
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(TestBulletNifLoader,
|
||||||
for_root_nif_node_with_bounds_but_without_flag_should_return_shape_with_bounds_but_with_null_collision_shape)
|
for_root_nif_node_with_bounds_but_without_flag_should_return_shape_with_bounds_but_with_null_collision_shape)
|
||||||
{
|
{
|
||||||
mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3);
|
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
|
||||||
mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3);
|
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
Nif::NIFFile file("test.nif");
|
Nif::NIFFile file("test.nif");
|
||||||
file.mRoots.push_back(&mNode);
|
file.mRoots.push_back(&mNode);
|
||||||
|
@ -608,9 +608,9 @@ namespace
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(TestBulletNifLoader,
|
||||||
for_tri_shape_root_node_with_bounds_should_return_static_shape_with_bounds_but_with_null_collision_shape)
|
for_tri_shape_root_node_with_bounds_should_return_static_shape_with_bounds_but_with_null_collision_shape)
|
||||||
{
|
{
|
||||||
mNiTriShape.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV;
|
mNiTriShape.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
|
||||||
mNiTriShape.mBounds.box.extents = osg::Vec3f(1, 2, 3);
|
mNiTriShape.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
|
||||||
mNiTriShape.mBounds.box.center = osg::Vec3f(-1, -2, -3);
|
mNiTriShape.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
|
||||||
|
|
||||||
Nif::NIFFile file("test.nif");
|
Nif::NIFFile file("test.nif");
|
||||||
file.mRoots.push_back(&mNiTriShape);
|
file.mRoots.push_back(&mNiTriShape);
|
||||||
|
@ -703,7 +703,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.mSkin = Nif::NiSkinInstancePtr(&mNiSkinInstance);
|
||||||
mNiTriShape.mParents.push_back(&mNiNode);
|
mNiTriShape.mParents.push_back(&mNiNode);
|
||||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
||||||
|
|
||||||
|
@ -943,7 +943,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.mParents.push_back(&mNiNode);
|
mNiTriShape.mParents.push_back(&mNiNode);
|
||||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
||||||
|
|
||||||
|
@ -961,7 +961,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->mTriangles.clear();
|
data->mTriangles.clear();
|
||||||
mNiTriShape.mParents.push_back(&mNiNode);
|
mNiTriShape.mParents.push_back(&mNiNode);
|
||||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
||||||
|
@ -1095,7 +1095,7 @@ namespace
|
||||||
init(niTriShape);
|
init(niTriShape);
|
||||||
init(emptyCollisionNode);
|
init(emptyCollisionNode);
|
||||||
|
|
||||||
niTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
niTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||||
niTriShape.mParents.push_back(&mNiNode);
|
niTriShape.mParents.push_back(&mNiNode);
|
||||||
|
|
||||||
emptyCollisionNode.recType = Nif::RC_RootCollisionNode;
|
emptyCollisionNode.recType = Nif::RC_RootCollisionNode;
|
||||||
|
@ -1192,21 +1192,6 @@ namespace
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, should_ignore_tri_shape_data_with_mismatching_data_rec_type)
|
|
||||||
{
|
|
||||||
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
|
||||||
|
|
||||||
Nif::NIFFile file("test.nif");
|
|
||||||
file.mRoots.push_back(&mNiTriShape);
|
|
||||||
file.mHash = mHash;
|
|
||||||
|
|
||||||
const auto result = mLoader.load(file);
|
|
||||||
|
|
||||||
const Resource::BulletShape expected;
|
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, for_tri_strips_root_node_should_return_static_shape)
|
TEST_F(TestBulletNifLoader, for_tri_strips_root_node_should_return_static_shape)
|
||||||
{
|
{
|
||||||
Nif::NIFFile file("test.nif");
|
Nif::NIFFile file("test.nif");
|
||||||
|
@ -1227,21 +1212,6 @@ namespace
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, should_ignore_tri_strips_data_with_mismatching_data_rec_type)
|
|
||||||
{
|
|
||||||
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
|
||||||
|
|
||||||
Nif::NIFFile file("test.nif");
|
|
||||||
file.mRoots.push_back(&mNiTriStrips);
|
|
||||||
file.mHash = mHash;
|
|
||||||
|
|
||||||
const auto result = mLoader.load(file);
|
|
||||||
|
|
||||||
const Resource::BulletShape expected;
|
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, should_ignore_tri_strips_data_with_empty_strips)
|
TEST_F(TestBulletNifLoader, should_ignore_tri_strips_data_with_empty_strips)
|
||||||
{
|
{
|
||||||
mNiTriStripsData.mStrips.clear();
|
mNiTriStripsData.mStrips.clear();
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "node.hpp"
|
#include "node.hpp"
|
||||||
|
|
||||||
#include <components/misc/strings/algorithm.hpp>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <components/misc/strings/algorithm.hpp>
|
||||||
|
|
||||||
#include "data.hpp"
|
#include "data.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "physics.hpp"
|
#include "physics.hpp"
|
||||||
|
@ -10,67 +11,65 @@
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
void NiBoundingVolume::read(NIFStream* nif)
|
|
||||||
|
void BoundingVolume::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
nif->read(type);
|
nif->read(mType);
|
||||||
switch (type)
|
switch (mType)
|
||||||
{
|
{
|
||||||
case BASE_BV:
|
case BASE_BV:
|
||||||
break;
|
break;
|
||||||
case SPHERE_BV:
|
case SPHERE_BV:
|
||||||
{
|
{
|
||||||
nif->read(sphere);
|
nif->read(mSphere);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BOX_BV:
|
case BOX_BV:
|
||||||
{
|
{
|
||||||
box.center = nif->getVector3();
|
nif->read(mBox.mCenter);
|
||||||
nif->read(box.axes);
|
nif->read(mBox.mAxes);
|
||||||
box.extents = nif->getVector3();
|
nif->read(mBox.mExtents);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CAPSULE_BV:
|
case CAPSULE_BV:
|
||||||
{
|
{
|
||||||
capsule.center = nif->getVector3();
|
nif->read(mCapsule.mCenter);
|
||||||
capsule.axis = nif->getVector3();
|
nif->read(mCapsule.mAxis);
|
||||||
capsule.extent = nif->getFloat();
|
nif->read(mCapsule.mExtent);
|
||||||
capsule.radius = nif->getFloat();
|
nif->read(mCapsule.mRadius);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LOZENGE_BV:
|
case LOZENGE_BV:
|
||||||
{
|
{
|
||||||
lozenge.radius = nif->getFloat();
|
nif->read(mLozenge.mRadius);
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 1, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 1, 0))
|
||||||
{
|
{
|
||||||
lozenge.extent0 = nif->getFloat();
|
nif->read(mLozenge.mExtent0);
|
||||||
lozenge.extent1 = nif->getFloat();
|
nif->read(mLozenge.mExtent1);
|
||||||
}
|
}
|
||||||
lozenge.center = nif->getVector3();
|
nif->read(mLozenge.mCenter);
|
||||||
lozenge.axis0 = nif->getVector3();
|
nif->read(mLozenge.mAxis0);
|
||||||
lozenge.axis1 = nif->getVector3();
|
nif->read(mLozenge.mAxis1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UNION_BV:
|
case UNION_BV:
|
||||||
{
|
{
|
||||||
unsigned int numChildren = nif->getUInt();
|
mChildren.resize(nif->get<uint32_t>());
|
||||||
if (numChildren == 0)
|
for (BoundingVolume& child : mChildren)
|
||||||
break;
|
|
||||||
children.resize(numChildren);
|
|
||||||
for (NiBoundingVolume& child : children)
|
|
||||||
child.read(nif);
|
child.read(nif);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HALFSPACE_BV:
|
case HALFSPACE_BV:
|
||||||
{
|
{
|
||||||
halfSpace.plane = osg::Plane(nif->getVector4());
|
mHalfSpace.mPlane = osg::Plane(nif->get<osg::Vec4f>());
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 1, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 1, 0))
|
||||||
halfSpace.origin = nif->getVector3();
|
nif->read(mHalfSpace.mOrigin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
throw Nif::Exception(
|
throw Nif::Exception(
|
||||||
"Unhandled NiBoundingVolume type: " + std::to_string(type), nif->getFile().getFilename());
|
"Unhandled BoundingVolume type: " + std::to_string(mType), nif->getFile().getFilename());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,125 +151,153 @@ namespace Nif
|
||||||
{
|
{
|
||||||
if (nif->getVersion() < NIFStream::generateVersion(10, 0, 1, 0))
|
if (nif->getVersion() < NIFStream::generateVersion(10, 0, 1, 0))
|
||||||
return;
|
return;
|
||||||
unsigned int num = 0;
|
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(20, 1, 0, 3) && nif->get<bool>())
|
|
||||||
num = 1;
|
|
||||||
else if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
|
|
||||||
num = nif->getUInt();
|
|
||||||
|
|
||||||
nif->readVector(names, num);
|
|
||||||
nif->readVector(extra, num);
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
|
if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
|
||||||
active = nif->getUInt();
|
mNames.resize(nif->get<uint32_t>());
|
||||||
|
else if (nif->getVersion() <= NIFStream::generateVersion(20, 1, 0, 3))
|
||||||
|
mNames.resize(nif->get<bool>());
|
||||||
|
nif->readVector(mNames, mNames.size());
|
||||||
|
nif->readVector(mExtra, mNames.size());
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(20, 2, 0, 5))
|
||||||
|
nif->read(mActive);
|
||||||
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
|
||||||
nif->read(needsUpdate);
|
nif->read(mNeedsUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiGeometry::read(NIFStream* nif)
|
void NiGeometry::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiAVObject::read(nif);
|
NiAVObject::read(nif);
|
||||||
data.read(nif);
|
|
||||||
skin.read(nif);
|
mData.read(nif);
|
||||||
material.read(nif);
|
if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13))
|
||||||
|
mSkin.read(nif);
|
||||||
|
mMaterial.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)
|
||||||
{
|
{
|
||||||
NiAVObject::post(nif);
|
NiAVObject::post(nif);
|
||||||
data.post(nif);
|
|
||||||
skin.post(nif);
|
mData.post(nif);
|
||||||
shaderprop.post(nif);
|
mSkin.post(nif);
|
||||||
alphaprop.post(nif);
|
mShaderProperty.post(nif);
|
||||||
if (recType != RC_NiParticles && !skin.empty())
|
mAlphaProperty.post(nif);
|
||||||
|
if (recType != RC_NiParticles && !mSkin.empty())
|
||||||
nif.setUseSkinning(true);
|
nif.setUseSkinning(true);
|
||||||
|
|
||||||
|
if (!mData.empty())
|
||||||
|
{
|
||||||
|
switch (recType)
|
||||||
|
{
|
||||||
|
case RC_NiTriShape:
|
||||||
|
case RC_BSLODTriShape:
|
||||||
|
if (mData->recType != RC_NiTriShapeData)
|
||||||
|
mData = NiGeometryDataPtr(nullptr);
|
||||||
|
break;
|
||||||
|
case RC_NiTriStrips:
|
||||||
|
if (mData->recType != RC_NiTriStripsData)
|
||||||
|
mData = NiGeometryDataPtr(nullptr);
|
||||||
|
break;
|
||||||
|
case RC_NiParticles:
|
||||||
|
if (mData->recType != RC_NiParticlesData)
|
||||||
|
mData = NiGeometryDataPtr(nullptr);
|
||||||
|
break;
|
||||||
|
case RC_NiLines:
|
||||||
|
if (mData->recType != RC_NiLinesData)
|
||||||
|
mData = NiGeometryDataPtr(nullptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSLODTriShape::read(NIFStream* nif)
|
void BSLODTriShape::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiTriShape::read(nif);
|
NiTriBasedGeom::read(nif);
|
||||||
lod0 = nif->getUInt();
|
|
||||||
lod1 = nif->getUInt();
|
|
||||||
lod2 = nif->getUInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NiCamera::Camera::read(NIFStream* nif)
|
nif->readArray(mLOD);
|
||||||
{
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
|
||||||
cameraFlags = nif->getUShort();
|
|
||||||
left = nif->getFloat();
|
|
||||||
right = nif->getFloat();
|
|
||||||
top = nif->getFloat();
|
|
||||||
bottom = nif->getFloat();
|
|
||||||
nearDist = nif->getFloat();
|
|
||||||
farDist = nif->getFloat();
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
|
||||||
nif->read(orthographic);
|
|
||||||
vleft = nif->getFloat();
|
|
||||||
vright = nif->getFloat();
|
|
||||||
vtop = nif->getFloat();
|
|
||||||
vbottom = nif->getFloat();
|
|
||||||
|
|
||||||
LOD = nif->getFloat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiCamera::read(NIFStream* nif)
|
void NiCamera::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiAVObject::read(nif);
|
NiAVObject::read(nif);
|
||||||
|
|
||||||
cam.read(nif);
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||||
|
nif->read(mCameraFlags);
|
||||||
nif->getInt(); // -1
|
nif->read(mLeft);
|
||||||
nif->getInt(); // 0
|
nif->read(mRight);
|
||||||
|
nif->read(mTop);
|
||||||
|
nif->read(mBottom);
|
||||||
|
nif->read(mNearDist);
|
||||||
|
nif->read(mFarDist);
|
||||||
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||||
|
nif->read(mOrthographic);
|
||||||
|
nif->read(mVLeft);
|
||||||
|
nif->read(mVRight);
|
||||||
|
nif->read(mVTop);
|
||||||
|
nif->read(mVBottom);
|
||||||
|
nif->read(mLODAdjust);
|
||||||
|
mScene.read(nif);
|
||||||
|
nif->skip(4); // Unused
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 1, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(4, 2, 1, 0))
|
||||||
nif->getInt(); // 0
|
nif->skip(4); // Unused
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiCamera::post(Reader& nif)
|
||||||
|
{
|
||||||
|
NiAVObject::post(nif);
|
||||||
|
|
||||||
|
mScene.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiSwitchNode::read(NIFStream* nif)
|
void NiSwitchNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiNode::read(nif);
|
NiNode::read(nif);
|
||||||
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||||
switchFlags = nif->getUShort();
|
nif->read(mSwitchFlags);
|
||||||
initialIndex = nif->getUInt();
|
nif->read(mInitialIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiLODNode::read(NIFStream* nif)
|
void NiLODNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiSwitchNode::read(nif);
|
NiSwitchNode::read(nif);
|
||||||
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW
|
|
||||||
&& nif->getVersion() <= NIFStream::generateVersion(10, 0, 1, 0))
|
if (nif->getVersion() > NIFStream::generateVersion(10, 0, 1, 0))
|
||||||
lodCenter = nif->getVector3();
|
|
||||||
else if (nif->getVersion() > NIFStream::generateVersion(10, 0, 1, 0))
|
|
||||||
{
|
{
|
||||||
nif->skip(4); // NiLODData, unsupported at the moment
|
nif->skip(4); // NiLODData, unsupported at the moment
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int numLodLevels = nif->getUInt();
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
|
||||||
for (unsigned int i = 0; i < numLodLevels; ++i)
|
nif->read(mLODCenter);
|
||||||
|
|
||||||
|
mLODLevels.resize(nif->get<uint32_t>());
|
||||||
|
for (LODRange& level : mLODLevels)
|
||||||
{
|
{
|
||||||
LODRange r;
|
nif->read(level.mMinRange);
|
||||||
r.minRange = nif->getFloat();
|
nif->read(level.mMaxRange);
|
||||||
r.maxRange = nif->getFloat();
|
|
||||||
lodLevels.push_back(r);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiFltAnimationNode::read(NIFStream* nif)
|
void NiFltAnimationNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiSwitchNode::read(nif);
|
NiSwitchNode::read(nif);
|
||||||
mDuration = nif->getFloat();
|
|
||||||
|
nif->read(mDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiSortAdjustNode::read(NIFStream* nif)
|
void NiSortAdjustNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiNode::read(nif);
|
NiNode::read(nif);
|
||||||
mMode = nif->getInt();
|
|
||||||
|
mMode = static_cast<SortingMode>(nif->get<uint32_t>());
|
||||||
if (nif->getVersion() <= NIFStream::generateVersion(20, 0, 0, 3))
|
if (nif->getVersion() <= NIFStream::generateVersion(20, 0, 0, 3))
|
||||||
mSubSorter.read(nif);
|
mSubSorter.read(nif);
|
||||||
}
|
}
|
||||||
|
@ -278,14 +305,16 @@ namespace Nif
|
||||||
void NiSortAdjustNode::post(Reader& nif)
|
void NiSortAdjustNode::post(Reader& nif)
|
||||||
{
|
{
|
||||||
NiNode::post(nif);
|
NiNode::post(nif);
|
||||||
|
|
||||||
mSubSorter.post(nif);
|
mSubSorter.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiBillboardNode::read(NIFStream* nif)
|
void NiBillboardNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiNode::read(nif);
|
NiNode::read(nif);
|
||||||
|
|
||||||
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
||||||
mMode = nif->getUShort() & 0x7;
|
mMode = nif->get<uint16_t>() & 0x7;
|
||||||
else
|
else
|
||||||
mMode = (mFlags >> 5) & 0x3;
|
mMode = (mFlags >> 5) & 0x3;
|
||||||
}
|
}
|
||||||
|
@ -293,8 +322,9 @@ namespace Nif
|
||||||
void NiDefaultAVObjectPalette::read(NIFStream* nif)
|
void NiDefaultAVObjectPalette::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
mScene.read(nif);
|
mScene.read(nif);
|
||||||
size_t numObjects = nif->getUInt();
|
uint32_t numObjects;
|
||||||
for (size_t i = 0; i < numObjects; i++)
|
nif->read(numObjects);
|
||||||
|
for (uint32_t i = 0; i < numObjects; i++)
|
||||||
mObjects[nif->getSizedString()].read(nif);
|
mObjects[nif->getSizedString()].read(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +338,7 @@ namespace Nif
|
||||||
void BSTreeNode::read(NIFStream* nif)
|
void BSTreeNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiNode::read(nif);
|
NiNode::read(nif);
|
||||||
|
|
||||||
readRecordList(nif, mBones1);
|
readRecordList(nif, mBones1);
|
||||||
readRecordList(nif, mBones2);
|
readRecordList(nif, mBones2);
|
||||||
}
|
}
|
||||||
|
@ -315,6 +346,7 @@ namespace Nif
|
||||||
void BSTreeNode::post(Reader& nif)
|
void BSTreeNode::post(Reader& nif)
|
||||||
{
|
{
|
||||||
NiNode::post(nif);
|
NiNode::post(nif);
|
||||||
|
|
||||||
postRecordList(nif, mBones1);
|
postRecordList(nif, mBones1);
|
||||||
postRecordList(nif, mBones2);
|
postRecordList(nif, mBones2);
|
||||||
}
|
}
|
||||||
|
@ -322,67 +354,53 @@ namespace Nif
|
||||||
void BSMultiBoundNode::read(NIFStream* nif)
|
void BSMultiBoundNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiNode::read(nif);
|
NiNode::read(nif);
|
||||||
|
|
||||||
mMultiBound.read(nif);
|
mMultiBound.read(nif);
|
||||||
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SKY)
|
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SKY)
|
||||||
mType = nif->getUInt();
|
mCullingType = static_cast<BSCPCullingType>(nif->get<uint32_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSMultiBoundNode::post(Reader& nif)
|
void BSMultiBoundNode::post(Reader& nif)
|
||||||
{
|
{
|
||||||
NiNode::post(nif);
|
NiNode::post(nif);
|
||||||
|
|
||||||
mMultiBound.post(nif);
|
mMultiBound.post(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSTriShape::read(NIFStream* nif)
|
void BSTriShape::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiAVObject::read(nif);
|
NiAVObject::read(nif);
|
||||||
nif->read(mBoundingSphere);
|
|
||||||
|
|
||||||
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_F76)
|
nif->read(mBoundingSphere);
|
||||||
{
|
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_F76)
|
||||||
nif->readArray(mBoundMinMax);
|
nif->readArray(mBoundMinMax);
|
||||||
}
|
|
||||||
|
|
||||||
mSkin.read(nif);
|
mSkin.read(nif);
|
||||||
mShaderProperty.read(nif);
|
mShaderProperty.read(nif);
|
||||||
mAlphaProperty.read(nif);
|
mAlphaProperty.read(nif);
|
||||||
|
|
||||||
mVertDesc.read(nif);
|
mVertDesc.read(nif);
|
||||||
|
|
||||||
unsigned int triNum;
|
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO4)
|
||||||
if (nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO4)
|
mTriangles.resize(nif->get<uint32_t>() * 3);
|
||||||
{
|
|
||||||
triNum = nif->get<unsigned short>();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
mTriangles.resize(nif->get<uint16_t>() * 3);
|
||||||
nif->read(triNum);
|
mVertData.resize(nif->get<uint16_t>());
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short vertNum;
|
|
||||||
nif->read(vertNum);
|
|
||||||
nif->read(mDataSize);
|
nif->read(mDataSize);
|
||||||
|
if (mDataSize > 0)
|
||||||
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE)
|
|
||||||
{
|
{
|
||||||
mVertData.resize(vertNum);
|
|
||||||
for (auto& vertex : mVertData)
|
for (auto& vertex : mVertData)
|
||||||
vertex.read(nif, mVertDesc.mFlags);
|
vertex.read(nif, mVertDesc.mFlags);
|
||||||
|
nif->readVector(mTriangles, mTriangles.size());
|
||||||
}
|
}
|
||||||
else if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_FO4)
|
|
||||||
{
|
|
||||||
throw Nif::Exception("FO4 BSTriShape is not supported yet: ", nif->getFile().getFilename());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mDataSize > 0)
|
|
||||||
nif->readVector(mTriangles, triNum * 3);
|
|
||||||
|
|
||||||
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE)
|
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_SSE)
|
||||||
{
|
{
|
||||||
nif->read(mParticleDataSize);
|
nif->read(mParticleDataSize);
|
||||||
if (mParticleDataSize > 0)
|
if (mParticleDataSize > 0)
|
||||||
{
|
{
|
||||||
throw Nif::Exception("Unhandled Particle Data in BSTriShape: ", nif->getFile().getFilename());
|
nif->readVector(mParticleVerts, mVertData.size() * 3);
|
||||||
|
nif->readVector(mParticleNormals, mVertData.size() * 3);
|
||||||
|
nif->readVector(mParticleTriangles, mTriangles.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,6 +408,7 @@ namespace Nif
|
||||||
void BSTriShape::post(Reader& nif)
|
void BSTriShape::post(Reader& nif)
|
||||||
{
|
{
|
||||||
NiAVObject::post(nif);
|
NiAVObject::post(nif);
|
||||||
|
|
||||||
mSkin.post(nif);
|
mSkin.post(nif);
|
||||||
mShaderProperty.post(nif);
|
mShaderProperty.post(nif);
|
||||||
mAlphaProperty.post(nif);
|
mAlphaProperty.post(nif);
|
||||||
|
@ -443,7 +462,6 @@ namespace Nif
|
||||||
if (normalsFlag)
|
if (normalsFlag)
|
||||||
{
|
{
|
||||||
nif->readArray(mNormal);
|
nif->readArray(mNormal);
|
||||||
|
|
||||||
nif->read(mBitangentY);
|
nif->read(mBitangentY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +469,6 @@ namespace Nif
|
||||||
== (BSVertexDesc::VertexAttribute::Normals | BSVertexDesc::VertexAttribute::Tangents))
|
== (BSVertexDesc::VertexAttribute::Normals | BSVertexDesc::VertexAttribute::Tangents))
|
||||||
{
|
{
|
||||||
nif->readArray(mTangent);
|
nif->readArray(mTangent);
|
||||||
|
|
||||||
nif->read(mBitangentZ);
|
nif->read(mBitangentZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,14 +485,14 @@ namespace Nif
|
||||||
|
|
||||||
if (flags & BSVertexDesc::VertexAttribute::Eye_Data)
|
if (flags & BSVertexDesc::VertexAttribute::Eye_Data)
|
||||||
{
|
{
|
||||||
throw Nif::Exception("Unhandled Eye Data in BSTriShape: ", nif->getFile().getFilename());
|
nif->read(mEyeData);
|
||||||
// nif->read(mEyeData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSValueNode::read(NIFStream* nif)
|
void BSValueNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiNode::read(nif);
|
NiNode::read(nif);
|
||||||
|
|
||||||
nif->read(mValue);
|
nif->read(mValue);
|
||||||
nif->read(mValueFlags);
|
nif->read(mValueFlags);
|
||||||
}
|
}
|
||||||
|
@ -483,6 +500,7 @@ namespace Nif
|
||||||
void BSOrderedNode::read(NIFStream* nif)
|
void BSOrderedNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiNode::read(nif);
|
NiNode::read(nif);
|
||||||
|
|
||||||
nif->read(mAlphaSortBound);
|
nif->read(mAlphaSortBound);
|
||||||
nif->read(mStaticBound);
|
nif->read(mStaticBound);
|
||||||
}
|
}
|
||||||
|
@ -490,8 +508,10 @@ namespace Nif
|
||||||
void BSRangeNode::read(NIFStream* nif)
|
void BSRangeNode::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
NiNode::read(nif);
|
NiNode::read(nif);
|
||||||
|
|
||||||
nif->read(mMin);
|
nif->read(mMin);
|
||||||
nif->read(mMax);
|
nif->read(mMax);
|
||||||
nif->read(mCurrent);
|
nif->read(mCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Nif
|
||||||
|
|
||||||
struct NiNode;
|
struct NiNode;
|
||||||
|
|
||||||
struct NiBoundingVolume
|
struct BoundingVolume
|
||||||
{
|
{
|
||||||
enum Type : uint32_t
|
enum Type : uint32_t
|
||||||
{
|
{
|
||||||
|
@ -28,36 +28,36 @@ namespace Nif
|
||||||
|
|
||||||
struct NiBoxBV
|
struct NiBoxBV
|
||||||
{
|
{
|
||||||
osg::Vec3f center;
|
osg::Vec3f mCenter;
|
||||||
Matrix3 axes;
|
Matrix3 mAxes;
|
||||||
osg::Vec3f extents;
|
osg::Vec3f mExtents;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiCapsuleBV
|
struct NiCapsuleBV
|
||||||
{
|
{
|
||||||
osg::Vec3f center, axis;
|
osg::Vec3f mCenter, mAxis;
|
||||||
float extent{ 0.f }, radius{ 0.f };
|
float mExtent{ 0.f }, mRadius{ 0.f };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiLozengeBV
|
struct NiLozengeBV
|
||||||
{
|
{
|
||||||
float radius{ 0.f }, extent0{ 0.f }, extent1{ 0.f };
|
float mRadius{ 0.f }, mExtent0{ 0.f }, mExtent1{ 0.f };
|
||||||
osg::Vec3f center, axis0, axis1;
|
osg::Vec3f mCenter, mAxis0, mAxis1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiHalfSpaceBV
|
struct NiHalfSpaceBV
|
||||||
{
|
{
|
||||||
osg::Plane plane;
|
osg::Plane mPlane;
|
||||||
osg::Vec3f origin;
|
osg::Vec3f mOrigin;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t type{ BASE_BV };
|
uint32_t mType{ BASE_BV };
|
||||||
osg::BoundingSpheref sphere;
|
osg::BoundingSpheref mSphere;
|
||||||
NiBoxBV box;
|
NiBoxBV mBox;
|
||||||
NiCapsuleBV capsule;
|
NiCapsuleBV mCapsule;
|
||||||
NiLozengeBV lozenge;
|
NiLozengeBV mLozenge;
|
||||||
std::vector<NiBoundingVolume> children;
|
std::vector<BoundingVolume> mChildren;
|
||||||
NiHalfSpaceBV halfSpace;
|
NiHalfSpaceBV mHalfSpace;
|
||||||
|
|
||||||
void read(NIFStream* nif);
|
void read(NIFStream* nif);
|
||||||
};
|
};
|
||||||
|
@ -68,7 +68,7 @@ namespace Nif
|
||||||
|
|
||||||
// NiAVObject is an object that is a part of the main NIF tree. It has
|
// NiAVObject is an object that is a part of the main NIF tree. It has
|
||||||
// a parent node (unless it's the root) and transformation relative to its parent.
|
// a parent node (unless it's the root) and transformation relative to its parent.
|
||||||
struct NiAVObject : public NiObjectNET
|
struct NiAVObject : NiObjectNET
|
||||||
{
|
{
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ namespace Nif
|
||||||
NiTransform mTransform;
|
NiTransform mTransform;
|
||||||
osg::Vec3f mVelocity;
|
osg::Vec3f mVelocity;
|
||||||
PropertyList mProperties;
|
PropertyList mProperties;
|
||||||
NiBoundingVolume mBounds;
|
BoundingVolume mBounds;
|
||||||
NiCollisionObjectPtr mCollision;
|
NiCollisionObjectPtr mCollision;
|
||||||
// Parent nodes for the node. Only types derived from NiNode can be parents.
|
// Parent nodes for the node. Only types derived from NiNode can be parents.
|
||||||
std::vector<NiNode*> mParents;
|
std::vector<NiNode*> mParents;
|
||||||
|
@ -119,7 +119,14 @@ namespace Nif
|
||||||
void post(Reader& nif) override;
|
void post(Reader& nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiGeometry : NiAVObject
|
struct GeometryInterface
|
||||||
|
{
|
||||||
|
NiSkinInstancePtr mSkin;
|
||||||
|
BSShaderPropertyPtr mShaderProperty;
|
||||||
|
NiAlphaPropertyPtr mAlphaProperty;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NiGeometry : NiAVObject, GeometryInterface
|
||||||
{
|
{
|
||||||
/* Possible flags:
|
/* Possible flags:
|
||||||
0x40 - mesh has no vertex normals ?
|
0x40 - mesh has no vertex normals ?
|
||||||
|
@ -130,97 +137,95 @@ namespace Nif
|
||||||
|
|
||||||
struct MaterialData
|
struct MaterialData
|
||||||
{
|
{
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> mNames;
|
||||||
std::vector<int> extra;
|
std::vector<int> mExtra;
|
||||||
unsigned int active{ 0 };
|
int32_t mActive{ -1 };
|
||||||
bool needsUpdate{ false };
|
bool mNeedsUpdate{ false };
|
||||||
|
|
||||||
void read(NIFStream* nif);
|
void read(NIFStream* nif);
|
||||||
};
|
};
|
||||||
|
|
||||||
NiGeometryDataPtr data;
|
NiGeometryDataPtr mData;
|
||||||
NiSkinInstancePtr skin;
|
MaterialData mMaterial;
|
||||||
MaterialData material;
|
|
||||||
BSShaderPropertyPtr shaderprop;
|
|
||||||
NiAlphaPropertyPtr alphaprop;
|
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
void post(Reader& nif) override;
|
void post(Reader& nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiTriShape : NiGeometry
|
// Abstract triangle-based geometry
|
||||||
|
struct NiTriBasedGeom : NiGeometry
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
struct BSLODTriShape : NiTriShape
|
|
||||||
{
|
struct NiTriShape : NiTriBasedGeom
|
||||||
unsigned int lod0, lod1, lod2;
|
|
||||||
void read(NIFStream* nif) override;
|
|
||||||
};
|
|
||||||
struct NiTriStrips : NiGeometry
|
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
struct NiLines : NiGeometry
|
|
||||||
|
struct NiTriStrips : NiTriBasedGeom
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NiLines : NiTriBasedGeom
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
struct NiParticles : NiGeometry
|
struct NiParticles : NiGeometry
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BSLODTriShape : NiTriBasedGeom
|
||||||
|
{
|
||||||
|
std::array<uint32_t, 3> mLOD;
|
||||||
|
void read(NIFStream* nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
struct NiCamera : NiAVObject
|
struct NiCamera : NiAVObject
|
||||||
{
|
{
|
||||||
struct Camera
|
uint16_t mCameraFlags{ 0 };
|
||||||
{
|
// Camera frustum
|
||||||
unsigned short cameraFlags{ 0 };
|
float mLeft, mRight, mTop, mBottom, mNearDist, mFarDist;
|
||||||
|
bool mOrthographic{ false };
|
||||||
// Camera frustrum
|
|
||||||
float left, right, top, bottom, nearDist, farDist;
|
|
||||||
|
|
||||||
// Viewport
|
// Viewport
|
||||||
float vleft, vright, vtop, vbottom;
|
float mVLeft, mVRight, mVTop, mVBottom;
|
||||||
|
float mLODAdjust;
|
||||||
// Level of detail modifier
|
NiAVObjectPtr mScene;
|
||||||
float LOD;
|
|
||||||
|
|
||||||
// Orthographic projection usage flag
|
|
||||||
bool orthographic{ false };
|
|
||||||
|
|
||||||
void read(NIFStream* nif);
|
|
||||||
};
|
|
||||||
Camera cam;
|
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
|
void post(Reader& nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A node used as the base to switch between child nodes, such as for LOD levels.
|
// A node used as the base to switch between child nodes, such as for LOD levels.
|
||||||
struct NiSwitchNode : public NiNode
|
struct NiSwitchNode : NiNode
|
||||||
{
|
{
|
||||||
unsigned int switchFlags{ 0 };
|
uint16_t mSwitchFlags;
|
||||||
unsigned int initialIndex{ 0 };
|
uint32_t mInitialIndex;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiLODNode : public NiSwitchNode
|
struct NiLODNode : NiSwitchNode
|
||||||
{
|
{
|
||||||
osg::Vec3f lodCenter;
|
|
||||||
|
|
||||||
struct LODRange
|
struct LODRange
|
||||||
{
|
{
|
||||||
float minRange;
|
float mMinRange;
|
||||||
float maxRange;
|
float mMaxRange;
|
||||||
};
|
};
|
||||||
std::vector<LODRange> lodLevels;
|
|
||||||
|
osg::Vec3f mLODCenter;
|
||||||
|
std::vector<LODRange> mLODLevels;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiFltAnimationNode : public NiSwitchNode
|
struct NiFltAnimationNode : NiSwitchNode
|
||||||
{
|
{
|
||||||
float mDuration;
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
Flag_Swing = 0x40
|
Flag_Swing = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
|
float mDuration;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
|
|
||||||
bool swing() const { return mFlags & Flag_Swing; }
|
bool swing() const { return mFlags & Flag_Swing; }
|
||||||
|
@ -236,20 +241,21 @@ namespace Nif
|
||||||
struct NiClusterAccumulator : NiAccumulator
|
struct NiClusterAccumulator : NiAccumulator
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiAlphaAccumulator : NiClusterAccumulator
|
struct NiAlphaAccumulator : NiClusterAccumulator
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiSortAdjustNode : NiNode
|
struct NiSortAdjustNode : NiNode
|
||||||
{
|
{
|
||||||
enum SortingMode
|
enum class SortingMode : uint32_t
|
||||||
{
|
{
|
||||||
SortingMode_Inherit,
|
Inherit,
|
||||||
SortingMode_Off,
|
Off,
|
||||||
SortingMode_Subsort
|
Subsort,
|
||||||
};
|
};
|
||||||
|
|
||||||
int mMode;
|
SortingMode mMode;
|
||||||
NiAccumulatorPtr mSubSorter;
|
NiAccumulatorPtr mSubSorter;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
|
@ -258,7 +264,7 @@ namespace Nif
|
||||||
|
|
||||||
struct NiBillboardNode : NiNode
|
struct NiBillboardNode : NiNode
|
||||||
{
|
{
|
||||||
int mMode{ 0 };
|
int mMode;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
@ -275,14 +281,24 @@ namespace Nif
|
||||||
struct BSTreeNode : NiNode
|
struct BSTreeNode : NiNode
|
||||||
{
|
{
|
||||||
NiAVObjectList mBones1, mBones2;
|
NiAVObjectList mBones1, mBones2;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
void post(Reader& nif) override;
|
void post(Reader& nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BSMultiBoundNode : NiNode
|
struct BSMultiBoundNode : NiNode
|
||||||
{
|
{
|
||||||
|
enum class BSCPCullingType : uint32_t
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
AllPass,
|
||||||
|
AllFail,
|
||||||
|
IgnoreMultiBounds,
|
||||||
|
ForceMultiBoundsNoUpdate,
|
||||||
|
};
|
||||||
|
|
||||||
BSMultiBoundPtr mMultiBound;
|
BSMultiBoundPtr mMultiBound;
|
||||||
unsigned int mType{ 0 };
|
BSCPCullingType mCullingType;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
void post(Reader& nif) override;
|
void post(Reader& nif) override;
|
||||||
|
@ -290,17 +306,17 @@ namespace Nif
|
||||||
|
|
||||||
struct BSVertexDesc
|
struct BSVertexDesc
|
||||||
{
|
{
|
||||||
unsigned char mVertexDataSize;
|
uint8_t mVertexDataSize;
|
||||||
unsigned char mDynamicVertexSize;
|
uint8_t mDynamicVertexSize;
|
||||||
unsigned char mUV1Offset;
|
uint8_t mUV1Offset;
|
||||||
unsigned char mUV2Offset;
|
uint8_t mUV2Offset;
|
||||||
unsigned char mNormalOffset;
|
uint8_t mNormalOffset;
|
||||||
unsigned char mTangentOffset;
|
uint8_t mTangentOffset;
|
||||||
unsigned char mColorOffset;
|
uint8_t mColorOffset;
|
||||||
unsigned char mSkinningDataOffset;
|
uint8_t mSkinningDataOffset;
|
||||||
unsigned char mLandscapeDataOffset;
|
uint8_t mLandscapeDataOffset;
|
||||||
unsigned char mEyeDataOffset;
|
uint8_t mEyeDataOffset;
|
||||||
unsigned short mFlags;
|
uint16_t mFlags;
|
||||||
|
|
||||||
enum VertexAttribute
|
enum VertexAttribute
|
||||||
{
|
{
|
||||||
|
@ -324,9 +340,8 @@ namespace Nif
|
||||||
{
|
{
|
||||||
osg::Vec3f mVertex;
|
osg::Vec3f mVertex;
|
||||||
float mBitangentX;
|
float mBitangentX;
|
||||||
unsigned int mUnusedW;
|
uint32_t mUnusedW;
|
||||||
std::array<Misc::float16_t, 2> mUV;
|
std::array<Misc::float16_t, 2> mUV;
|
||||||
|
|
||||||
std::array<char, 3> mNormal;
|
std::array<char, 3> mNormal;
|
||||||
char mBitangentY;
|
char mBitangentY;
|
||||||
std::array<char, 3> mTangent;
|
std::array<char, 3> mTangent;
|
||||||
|
@ -339,25 +354,18 @@ namespace Nif
|
||||||
void read(NIFStream* nif, uint16_t flags);
|
void read(NIFStream* nif, uint16_t flags);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BSTriShape : NiAVObject
|
struct BSTriShape : NiAVObject, GeometryInterface
|
||||||
{
|
{
|
||||||
osg::BoundingSpheref mBoundingSphere;
|
osg::BoundingSpheref mBoundingSphere;
|
||||||
std::array<float, 6> mBoundMinMax;
|
std::array<float, 6> mBoundMinMax;
|
||||||
|
|
||||||
NiSkinInstancePtr mSkin;
|
|
||||||
BSShaderPropertyPtr mShaderProperty;
|
|
||||||
NiAlphaPropertyPtr mAlphaProperty;
|
|
||||||
|
|
||||||
BSVertexDesc mVertDesc;
|
BSVertexDesc mVertDesc;
|
||||||
|
uint32_t mDataSize;
|
||||||
unsigned int mDataSize;
|
|
||||||
unsigned int mParticleDataSize;
|
|
||||||
|
|
||||||
std::vector<BSVertexData> mVertData;
|
std::vector<BSVertexData> mVertData;
|
||||||
std::vector<unsigned short> mTriangles;
|
std::vector<unsigned short> mTriangles;
|
||||||
|
uint32_t mParticleDataSize;
|
||||||
|
std::vector<Misc::float16_t> mParticleVerts;
|
||||||
|
std::vector<Misc::float16_t> mParticleNormals;
|
||||||
std::vector<unsigned short> mParticleTriangles;
|
std::vector<unsigned short> mParticleTriangles;
|
||||||
std::vector<osg::Vec3f> mParticleVerts;
|
|
||||||
std::vector<osg::Vec3f> mParticleNormals;
|
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
void post(Reader& nif) override;
|
void post(Reader& nif) override;
|
||||||
|
@ -365,8 +373,14 @@ namespace Nif
|
||||||
|
|
||||||
struct BSValueNode : NiNode
|
struct BSValueNode : NiNode
|
||||||
{
|
{
|
||||||
unsigned int mValue;
|
enum Flags
|
||||||
char mValueFlags;
|
{
|
||||||
|
Flag_BillboardWorldZ = 0x1,
|
||||||
|
Flag_UsePlayerAdjust = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t mValue;
|
||||||
|
uint8_t mValueFlags;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
@ -374,7 +388,7 @@ namespace Nif
|
||||||
struct BSOrderedNode : NiNode
|
struct BSOrderedNode : NiNode
|
||||||
{
|
{
|
||||||
osg::Vec4f mAlphaSortBound;
|
osg::Vec4f mAlphaSortBound;
|
||||||
char mStaticBound;
|
bool mStaticBound;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,14 +79,11 @@ 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)
|
auto data = static_cast<const Nif::NiTriShapeData*>(geometry.mData.getPtr());
|
||||||
return {};
|
|
||||||
|
|
||||||
auto data = static_cast<const Nif::NiTriShapeData*>(geometry.data.getPtr());
|
|
||||||
if (data->mTriangles.empty())
|
if (data->mTriangles.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -95,10 +92,7 @@ namespace
|
||||||
|
|
||||||
if (geometry.recType == Nif::RC_NiTriStrips)
|
if (geometry.recType == Nif::RC_NiTriStrips)
|
||||||
{
|
{
|
||||||
if (geometry.data->recType != Nif::RC_NiTriStripsData)
|
auto data = static_cast<const Nif::NiTriStripsData*>(geometry.mData.getPtr());
|
||||||
return {};
|
|
||||||
|
|
||||||
auto data = static_cast<const Nif::NiTriStripsData*>(geometry.data.getPtr());
|
|
||||||
if (data->mStrips.empty())
|
if (data->mStrips.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -181,7 +175,7 @@ namespace NifBullet
|
||||||
bool hasCollisionShape = false;
|
bool hasCollisionShape = false;
|
||||||
if (colNode != nullptr)
|
if (colNode != nullptr)
|
||||||
{
|
{
|
||||||
if (colNode->mBounds.type == Nif::NiBoundingVolume::Type::BASE_BV && !colNode->mChildren.empty())
|
if (colNode->mBounds.mType == Nif::BoundingVolume::Type::BASE_BV && !colNode->mChildren.empty())
|
||||||
hasCollisionShape = true;
|
hasCollisionShape = true;
|
||||||
else
|
else
|
||||||
mShape->mVisualCollisionType = Resource::VisualCollisionType::Camera;
|
mShape->mVisualCollisionType = Resource::VisualCollisionType::Camera;
|
||||||
|
@ -205,25 +199,25 @@ namespace NifBullet
|
||||||
// Return: use bounding box for collision?
|
// Return: use bounding box for collision?
|
||||||
bool BulletNifLoader::findBoundingBox(const Nif::NiAVObject& node, const std::string& filename)
|
bool BulletNifLoader::findBoundingBox(const Nif::NiAVObject& node, const std::string& filename)
|
||||||
{
|
{
|
||||||
unsigned int type = node.mBounds.type;
|
unsigned int type = node.mBounds.mType;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case Nif::NiBoundingVolume::Type::BASE_BV:
|
case Nif::BoundingVolume::Type::BASE_BV:
|
||||||
break;
|
break;
|
||||||
case Nif::NiBoundingVolume::Type::BOX_BV:
|
case Nif::BoundingVolume::Type::BOX_BV:
|
||||||
mShape->mCollisionBox.mExtents = node.mBounds.box.extents;
|
mShape->mCollisionBox.mExtents = node.mBounds.mBox.mExtents;
|
||||||
mShape->mCollisionBox.mCenter = node.mBounds.box.center;
|
mShape->mCollisionBox.mCenter = node.mBounds.mBox.mCenter;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
std::stringstream warning;
|
std::stringstream warning;
|
||||||
warning << "Unsupported NiBoundingVolume type " << type << " in node " << node.recIndex;
|
warning << "Unsupported BoundingVolume type " << type << " in node " << node.recIndex;
|
||||||
warning << " in file " << filename;
|
warning << " in file " << filename;
|
||||||
warn(warning.str());
|
warn(warning.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != Nif::NiBoundingVolume::Type::BASE_BV && node.hasBBoxCollision())
|
if (type != Nif::BoundingVolume::Type::BASE_BV && node.hasBBoxCollision())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (const Nif::NiNode* ninode = dynamic_cast<const Nif::NiNode*>(&node))
|
if (const Nif::NiNode* ninode = dynamic_cast<const Nif::NiNode*>(&node))
|
||||||
|
@ -335,7 +329,7 @@ namespace NifBullet
|
||||||
// NOTE: a trishape with bounds, but no BBoxCollision flag should NOT go through handleNiTriShape!
|
// NOTE: a trishape with bounds, but no BBoxCollision flag should NOT go through handleNiTriShape!
|
||||||
// It must be ignored completely.
|
// It must be ignored completely.
|
||||||
// (occurs in tr_ex_imp_wall_arch_04.nif)
|
// (occurs in tr_ex_imp_wall_arch_04.nif)
|
||||||
if (node.mBounds.type == Nif::NiBoundingVolume::Type::BASE_BV
|
if (node.mBounds.mType == Nif::BoundingVolume::Type::BASE_BV
|
||||||
&& (node.recType == Nif::RC_NiTriShape || node.recType == Nif::RC_NiTriStrips
|
&& (node.recType == Nif::RC_NiTriShape || node.recType == Nif::RC_NiTriStrips
|
||||||
|| node.recType == Nif::RC_BSLODTriShape))
|
|| node.recType == Nif::RC_BSLODTriShape))
|
||||||
{
|
{
|
||||||
|
@ -366,10 +360,10 @@ namespace NifBullet
|
||||||
if (args.mHasMarkers && Misc::StringUtils::ciStartsWith(niGeometry.mName, "EditorMarker"))
|
if (args.mHasMarkers && Misc::StringUtils::ciStartsWith(niGeometry.mName, "EditorMarker"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (niGeometry.data.empty() || niGeometry.data->mVertices.empty())
|
if (niGeometry.mData.empty() || niGeometry.mData->mVertices.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!niGeometry.skin.empty())
|
if (!niGeometry.mSkin.empty())
|
||||||
args.mAnimated = false;
|
args.mAnimated = false;
|
||||||
// TODO: handle NiSkinPartition
|
// TODO: handle NiSkinPartition
|
||||||
|
|
||||||
|
|
|
@ -128,10 +128,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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,8 +444,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,11 +463,11 @@ namespace NifOsg
|
||||||
osg::ref_ptr<osg::LOD> lod(new osg::LOD);
|
osg::ref_ptr<osg::LOD> lod(new osg::LOD);
|
||||||
lod->setName(niLodNode->mName);
|
lod->setName(niLodNode->mName);
|
||||||
lod->setCenterMode(osg::LOD::USER_DEFINED_CENTER);
|
lod->setCenterMode(osg::LOD::USER_DEFINED_CENTER);
|
||||||
lod->setCenter(niLodNode->lodCenter);
|
lod->setCenter(niLodNode->mLODCenter);
|
||||||
for (unsigned int i = 0; i < niLodNode->lodLevels.size(); ++i)
|
for (unsigned int i = 0; i < niLodNode->mLODLevels.size(); ++i)
|
||||||
{
|
{
|
||||||
const Nif::NiLODNode::LODRange& range = niLodNode->lodLevels[i];
|
const Nif::NiLODNode::LODRange& range = niLodNode->mLODLevels[i];
|
||||||
lod->setRange(i, range.minRange, range.maxRange);
|
lod->setRange(i, range.mMinRange, range.mMaxRange);
|
||||||
}
|
}
|
||||||
lod->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
lod->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
||||||
return lod;
|
return lod;
|
||||||
|
@ -478,7 +478,7 @@ namespace NifOsg
|
||||||
osg::ref_ptr<osg::Switch> switchNode(new osg::Switch);
|
osg::ref_ptr<osg::Switch> switchNode(new osg::Switch);
|
||||||
switchNode->setName(niSwitchNode->mName);
|
switchNode->setName(niSwitchNode->mName);
|
||||||
switchNode->setNewChildDefaultValue(false);
|
switchNode->setNewChildDefaultValue(false);
|
||||||
switchNode->setSingleChildOn(niSwitchNode->initialIndex);
|
switchNode->setSingleChildOn(niSwitchNode->mInitialIndex);
|
||||||
return switchNode;
|
return switchNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ namespace NifOsg
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mPushedSorter && !mPushedSorter->mSubSorter.empty()
|
if (mPushedSorter && !mPushedSorter->mSubSorter.empty()
|
||||||
&& mPushedSorter->mMode != Nif::NiSortAdjustNode::SortingMode_Inherit)
|
&& mPushedSorter->mMode != Nif::NiSortAdjustNode::SortingMode::Inherit)
|
||||||
mLastAppliedNoInheritSorter = mPushedSorter;
|
mLastAppliedNoInheritSorter = mPushedSorter;
|
||||||
mPushedSorter = sortNode;
|
mPushedSorter = sortNode;
|
||||||
}
|
}
|
||||||
|
@ -761,7 +761,7 @@ namespace NifOsg
|
||||||
skip = args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->mName, "EditorMarker");
|
skip = args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->mName, "EditorMarker");
|
||||||
if (!skip)
|
if (!skip)
|
||||||
{
|
{
|
||||||
Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->skin;
|
Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->mSkin;
|
||||||
|
|
||||||
if (skin.empty())
|
if (skin.empty())
|
||||||
handleGeometry(nifNode, parent, node, composite, args.mBoundTextures, args.mAnimFlags);
|
handleGeometry(nifNode, parent, node, composite, args.mBoundTextures, args.mAnimFlags);
|
||||||
|
@ -1121,13 +1121,13 @@ namespace NifOsg
|
||||||
const Nif::NiAVObject* nifNode, ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl)
|
const Nif::NiAVObject* 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())
|
||||||
{
|
{
|
||||||
partsys->setQuota(partctrl->mParticles.size());
|
partsys->setQuota(partctrl->mParticles.size());
|
||||||
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->mNumParticles);
|
partsys->setQuota(particledata->mNumParticles);
|
||||||
|
|
||||||
osg::BoundingBox box;
|
osg::BoundingBox box;
|
||||||
|
@ -1379,13 +1379,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->mSkin.empty())
|
||||||
{
|
{
|
||||||
const Nif::NiSkinInstance* skin = niGeometry->skin.getPtr();
|
const Nif::NiSkinInstance* skin = niGeometry->mSkin.getPtr();
|
||||||
const Nif::NiSkinData* data = nullptr;
|
const Nif::NiSkinData* data = nullptr;
|
||||||
const Nif::NiSkinPartition* partitions = nullptr;
|
const Nif::NiSkinPartition* partitions = nullptr;
|
||||||
if (!skin->mData.empty())
|
if (!skin->mData.empty())
|
||||||
|
@ -1419,13 +1419,11 @@ 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)
|
||||||
{
|
{
|
||||||
if (niGeometryData->recType != Nif::RC_NiTriShapeData)
|
|
||||||
return;
|
|
||||||
auto data = static_cast<const Nif::NiTriShapeData*>(niGeometryData);
|
auto data = static_cast<const Nif::NiTriShapeData*>(niGeometryData);
|
||||||
const std::vector<unsigned short>& triangles = data->mTriangles;
|
const std::vector<unsigned short>& triangles = data->mTriangles;
|
||||||
if (triangles.empty())
|
if (triangles.empty())
|
||||||
|
@ -1435,8 +1433,6 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
else if (niGeometry->recType == Nif::RC_NiTriStrips)
|
else if (niGeometry->recType == Nif::RC_NiTriStrips)
|
||||||
{
|
{
|
||||||
if (niGeometryData->recType != Nif::RC_NiTriStripsData)
|
|
||||||
return;
|
|
||||||
auto data = static_cast<const Nif::NiTriStripsData*>(niGeometryData);
|
auto data = static_cast<const Nif::NiTriStripsData*>(niGeometryData);
|
||||||
bool hasGeometry = false;
|
bool hasGeometry = false;
|
||||||
for (const std::vector<unsigned short>& strip : data->mStrips)
|
for (const std::vector<unsigned short>& strip : data->mStrips)
|
||||||
|
@ -1452,8 +1448,6 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
else if (niGeometry->recType == Nif::RC_NiLines)
|
else if (niGeometry->recType == Nif::RC_NiLines)
|
||||||
{
|
{
|
||||||
if (niGeometryData->recType != Nif::RC_NiLinesData)
|
|
||||||
return;
|
|
||||||
auto data = static_cast<const Nif::NiLinesData*>(niGeometryData);
|
auto data = static_cast<const Nif::NiLinesData*>(niGeometryData);
|
||||||
const auto& line = data->mLines;
|
const auto& line = data->mLines;
|
||||||
if (line.empty())
|
if (line.empty())
|
||||||
|
@ -1545,7 +1539,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)->mSkin.getPtr();
|
||||||
const Nif::NiSkinData* data = skin->mData.getPtr();
|
const Nif::NiSkinData* data = skin->mData.getPtr();
|
||||||
const Nif::NiAVObjectList& bones = skin->mBones;
|
const Nif::NiAVObjectList& bones = skin->mBones;
|
||||||
for (std::size_t i = 0; i < bones.size(); ++i)
|
for (std::size_t i = 0; i < bones.size(); ++i)
|
||||||
|
@ -2627,8 +2621,8 @@ namespace NifOsg
|
||||||
if (!mPushedSorter)
|
if (!mPushedSorter)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto assignBin = [&](int mode, int type) {
|
auto assignBin = [&](Nif::NiSortAdjustNode::SortingMode mode, int type) {
|
||||||
if (mode == Nif::NiSortAdjustNode::SortingMode_Off)
|
if (mode == Nif::NiSortAdjustNode::SortingMode::Off)
|
||||||
{
|
{
|
||||||
setBin_Traversal(stateset);
|
setBin_Traversal(stateset);
|
||||||
return;
|
return;
|
||||||
|
@ -2649,7 +2643,7 @@ namespace NifOsg
|
||||||
|
|
||||||
switch (mPushedSorter->mMode)
|
switch (mPushedSorter->mMode)
|
||||||
{
|
{
|
||||||
case Nif::NiSortAdjustNode::SortingMode_Inherit:
|
case Nif::NiSortAdjustNode::SortingMode::Inherit:
|
||||||
{
|
{
|
||||||
if (mLastAppliedNoInheritSorter)
|
if (mLastAppliedNoInheritSorter)
|
||||||
assignBin(mLastAppliedNoInheritSorter->mMode, mLastAppliedNoInheritSorter->mSubSorter->recType);
|
assignBin(mLastAppliedNoInheritSorter->mMode, mLastAppliedNoInheritSorter->mSubSorter->recType);
|
||||||
|
@ -2657,12 +2651,12 @@ namespace NifOsg
|
||||||
assignBin(mPushedSorter->mMode, Nif::RC_NiAlphaAccumulator);
|
assignBin(mPushedSorter->mMode, Nif::RC_NiAlphaAccumulator);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Nif::NiSortAdjustNode::SortingMode_Off:
|
case Nif::NiSortAdjustNode::SortingMode::Off:
|
||||||
{
|
{
|
||||||
setBin_Traversal(stateset);
|
setBin_Traversal(stateset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Nif::NiSortAdjustNode::SortingMode_Subsort:
|
case Nif::NiSortAdjustNode::SortingMode::Subsort:
|
||||||
{
|
{
|
||||||
assignBin(mPushedSorter->mMode, mPushedSorter->mSubSorter->recType);
|
assignBin(mPushedSorter->mMode, mPushedSorter->mSubSorter->recType);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue