diff --git a/apps/openmw_test_suite/nif/node.hpp b/apps/openmw_test_suite/nif/node.hpp index 70a1fe16be..b39729c876 100644 --- a/apps/openmw_test_suite/nif/node.hpp +++ b/apps/openmw_test_suite/nif/node.hpp @@ -23,18 +23,16 @@ namespace Nif::Testing value.mController = ControllerPtr(nullptr); } - inline void init(Node& value) + inline void init(NiAVObject& value) { init(static_cast(value)); - value.flags = 0; - init(value.trafo); - value.hasBounds = false; - value.isBone = false; + value.mFlags = 0; + init(value.mTransform); } inline void init(NiGeometry& value) { - init(static_cast(value)); + init(static_cast(value)); value.data = NiGeometryDataPtr(nullptr); value.skin = NiSkinInstancePtr(nullptr); } @@ -54,7 +52,7 @@ namespace Nif::Testing inline void init(NiSkinInstance& value) { value.mData = NiSkinDataPtr(nullptr); - value.mRoot = NodePtr(nullptr); + value.mRoot = NiAVObjectPtr(nullptr); } inline void init(Controller& value) diff --git a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp index 2381d2d5a4..fc6a21f62c 100644 --- a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp +++ b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp @@ -285,8 +285,8 @@ namespace struct TestBulletNifLoader : Test { BulletNifLoader mLoader; - Nif::Node mNode; - Nif::Node mNode2; + Nif::NiAVObject mNode; + Nif::NiAVObject mNode2; Nif::NiNode mNiNode; Nif::NiNode mNiNode2; Nif::NiNode mNiNode3; @@ -414,11 +414,10 @@ namespace TEST_F( TestBulletNifLoader, for_root_nif_node_with_bounding_box_should_return_shape_with_compound_shape_and_box_inside) { - mNode.hasBounds = true; - mNode.flags |= Nif::Node::Flag_BBoxCollision; - mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); - mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); + mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision; + mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNode); @@ -439,13 +438,12 @@ namespace TEST_F(TestBulletNifLoader, for_child_nif_node_with_bounding_box) { - mNode.hasBounds = true; - mNode.flags |= Nif::Node::Flag_BBoxCollision; - mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); - mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); - mNode.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNode) })); + mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision; + mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3); + mNode.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -467,18 +465,16 @@ namespace TEST_F(TestBulletNifLoader, for_root_and_child_nif_node_with_bounding_box_but_root_without_flag_should_use_child_bounds) { - mNode.hasBounds = true; - mNode.flags |= Nif::Node::Flag_BBoxCollision; - mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); - mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); - mNode.parents.push_back(&mNiNode); - - mNiNode.hasBounds = true; - mNiNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNiNode.bounds.box.extents = osg::Vec3f(4, 5, 6); - mNiNode.bounds.box.center = osg::Vec3f(-4, -5, -6); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNode) })); + mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision; + mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3); + mNode.mParents.push_back(&mNiNode); + + mNiNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNiNode.mBounds.box.extents = osg::Vec3f(4, 5, 6); + mNiNode.mBounds.box.center = osg::Vec3f(-4, -5, -6); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -500,24 +496,21 @@ namespace TEST_F(TestBulletNifLoader, for_root_and_two_children_where_both_with_bounds_but_only_first_with_flag_should_use_first_bounds) { - mNode.hasBounds = true; - mNode.flags |= Nif::Node::Flag_BBoxCollision; - mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); - mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); - mNode.parents.push_back(&mNiNode); - - mNode2.hasBounds = true; - mNode2.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNode2.bounds.box.extents = osg::Vec3f(4, 5, 6); - mNode2.bounds.box.center = osg::Vec3f(-4, -5, -6); - mNode2.parents.push_back(&mNiNode); - - mNiNode.hasBounds = true; - mNiNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNiNode.bounds.box.extents = osg::Vec3f(7, 8, 9); - mNiNode.bounds.box.center = osg::Vec3f(-7, -8, -9); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2) })); + mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision; + mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3); + mNode.mParents.push_back(&mNiNode); + + mNode2.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode2.mBounds.box.extents = osg::Vec3f(4, 5, 6); + mNode2.mBounds.box.center = osg::Vec3f(-4, -5, -6); + mNode2.mParents.push_back(&mNiNode); + + mNiNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNiNode.mBounds.box.extents = osg::Vec3f(7, 8, 9); + mNiNode.mBounds.box.center = osg::Vec3f(-7, -8, -9); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode), Nif::NiAVObjectPtr(&mNode2) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -539,24 +532,21 @@ namespace TEST_F(TestBulletNifLoader, for_root_and_two_children_where_both_with_bounds_but_only_second_with_flag_should_use_second_bounds) { - mNode.hasBounds = true; - mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); - mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); - mNode.parents.push_back(&mNiNode); - - mNode2.hasBounds = true; - mNode2.flags |= Nif::Node::Flag_BBoxCollision; - mNode2.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNode2.bounds.box.extents = osg::Vec3f(4, 5, 6); - mNode2.bounds.box.center = osg::Vec3f(-4, -5, -6); - mNode2.parents.push_back(&mNiNode); - - mNiNode.hasBounds = true; - mNiNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNiNode.bounds.box.extents = osg::Vec3f(7, 8, 9); - mNiNode.bounds.box.center = osg::Vec3f(-7, -8, -9); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2) })); + mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3); + mNode.mParents.push_back(&mNiNode); + + mNode2.mFlags |= Nif::NiAVObject::Flag_BBoxCollision; + mNode2.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode2.mBounds.box.extents = osg::Vec3f(4, 5, 6); + mNode2.mBounds.box.center = osg::Vec3f(-4, -5, -6); + mNode2.mParents.push_back(&mNiNode); + + mNiNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNiNode.mBounds.box.extents = osg::Vec3f(7, 8, 9); + mNiNode.mBounds.box.center = osg::Vec3f(-7, -8, -9); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNode), Nif::NiAVObjectPtr(&mNode2) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -578,10 +568,9 @@ namespace TEST_F(TestBulletNifLoader, for_root_nif_node_with_bounds_but_without_flag_should_return_shape_with_bounds_but_with_null_collision_shape) { - mNode.hasBounds = true; - mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); - mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); + mNode.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.mBounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.mBounds.box.center = osg::Vec3f(-1, -2, -3); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNode); @@ -619,10 +608,9 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_root_node_with_bounds_should_return_static_shape_with_bounds_but_with_null_collision_shape) { - mNiTriShape.hasBounds = true; - mNiTriShape.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; - mNiTriShape.bounds.box.extents = osg::Vec3f(1, 2, 3); - mNiTriShape.bounds.box.center = osg::Vec3f(-1, -2, -3); + mNiTriShape.mBounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNiTriShape.mBounds.box.extents = osg::Vec3f(1, 2, 3); + mNiTriShape.mBounds.box.center = osg::Vec3f(-1, -2, -3); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiTriShape); @@ -639,8 +627,8 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_should_return_static_shape) { - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -662,10 +650,10 @@ namespace TEST_F(TestBulletNifLoader, for_nested_tri_shape_child_should_return_static_shape) { - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiNode2) })); - mNiNode2.parents.push_back(&mNiNode); - mNiNode2.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); - mNiTriShape.parents.push_back(&mNiNode2); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiNode2) }; + mNiNode2.mParents.push_back(&mNiNode); + mNiNode2.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; + mNiTriShape.mParents.push_back(&mNiNode2); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -687,10 +675,9 @@ namespace TEST_F(TestBulletNifLoader, for_two_tri_shape_children_should_return_static_shape_with_all_meshes) { - mNiTriShape.parents.push_back(&mNiNode); - mNiTriShape2.parents.push_back(&mNiNode); - mNiNode.children - = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape), Nif::NodePtr(&mNiTriShape2) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiTriShape2.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape), Nif::NiAVObjectPtr(&mNiTriShape2) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -717,8 +704,8 @@ namespace for_tri_shape_child_node_and_filename_starting_with_x_and_not_empty_skin_should_return_static_shape) { mNiTriShape.skin = Nif::NiSkinInstancePtr(&mNiSkinInstance); - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("xtest.nif"); file.mRoots.push_back(&mNiNode); @@ -739,8 +726,8 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_root_node_and_filename_starting_with_x_should_return_animated_shape) { - copy(mTransform, mNiTriShape.trafo); - mNiTriShape.trafo.mScale = 3; + copy(mTransform, mNiTriShape.mTransform); + mNiTriShape.mTransform.mScale = 3; Nif::NIFFile file("xtest.nif"); file.mRoots.push_back(&mNiTriShape); @@ -763,11 +750,11 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_and_filename_starting_with_x_should_return_animated_shape) { - copy(mTransform, mNiTriShape.trafo); - mNiTriShape.trafo.mScale = 3; - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); - mNiNode.trafo.mScale = 4; + copy(mTransform, mNiTriShape.mTransform); + mNiTriShape.mTransform.mScale = 3; + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; + mNiNode.mTransform.mScale = 4; Nif::NIFFile file("xtest.nif"); file.mRoots.push_back(&mNiNode); @@ -791,18 +778,15 @@ namespace TEST_F( TestBulletNifLoader, for_two_tri_shape_children_nodes_and_filename_starting_with_x_should_return_animated_shape) { - copy(mTransform, mNiTriShape.trafo); - mNiTriShape.trafo.mScale = 3; - mNiTriShape.parents.push_back(&mNiNode); + copy(mTransform, mNiTriShape.mTransform); + mNiTriShape.mTransform.mScale = 3; + mNiTriShape.mParents.push_back(&mNiNode); - copy(mTransform, mNiTriShape2.trafo); - mNiTriShape2.trafo.mScale = 3; - mNiTriShape2.parents.push_back(&mNiNode); + copy(mTransform, mNiTriShape2.mTransform); + mNiTriShape2.mTransform.mScale = 3; + mNiTriShape2.mParents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ - Nif::NodePtr(&mNiTriShape), - Nif::NodePtr(&mNiTriShape2), - })); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape), Nif::NiAVObjectPtr(&mNiTriShape2) }; Nif::NIFFile file("xtest.nif"); file.mRoots.push_back(&mNiNode); @@ -834,12 +818,12 @@ namespace { mController.recType = Nif::RC_NiKeyframeController; mController.flags |= Nif::Controller::Flag_Active; - copy(mTransform, mNiTriShape.trafo); - mNiTriShape.trafo.mScale = 3; - mNiTriShape.parents.push_back(&mNiNode); + copy(mTransform, mNiTriShape.mTransform); + mNiTriShape.mTransform.mScale = 3; + mNiTriShape.mParents.push_back(&mNiNode); mNiTriShape.mController = Nif::ControllerPtr(&mController); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); - mNiNode.trafo.mScale = 4; + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; + mNiNode.mTransform.mScale = 4; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -864,18 +848,18 @@ namespace { mController.recType = Nif::RC_NiKeyframeController; mController.flags |= Nif::Controller::Flag_Active; - copy(mTransform, mNiTriShape.trafo); - mNiTriShape.trafo.mScale = 3; - mNiTriShape.parents.push_back(&mNiNode); - copy(mTransform, mNiTriShape2.trafo); - mNiTriShape2.trafo.mScale = 3; - mNiTriShape2.parents.push_back(&mNiNode); + copy(mTransform, mNiTriShape.mTransform); + mNiTriShape.mTransform.mScale = 3; + mNiTriShape.mParents.push_back(&mNiNode); + copy(mTransform, mNiTriShape2.mTransform); + mNiTriShape2.mTransform.mScale = 3; + mNiTriShape2.mParents.push_back(&mNiNode); mNiTriShape2.mController = Nif::ControllerPtr(&mController); - mNiNode.children = Nif::NodeList(std::vector({ - Nif::NodePtr(&mNiTriShape), - Nif::NodePtr(&mNiTriShape2), - })); - mNiNode.trafo.mScale = 4; + mNiNode.mChildren = Nif::NiAVObjectList{ + Nif::NiAVObjectPtr(&mNiTriShape), + Nif::NiAVObjectPtr(&mNiTriShape2), + }; + mNiNode.mTransform.mScale = 4; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -905,8 +889,8 @@ namespace TEST_F(TestBulletNifLoader, should_add_static_mesh_to_existing_compound_mesh) { - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("xtest.nif"); file.mRoots.push_back(&mNiNode); @@ -936,8 +920,8 @@ namespace TEST_F( TestBulletNifLoader, for_root_avoid_node_and_tri_shape_child_node_should_return_shape_with_null_collision_shape) { - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; mNiNode.recType = Nif::RC_AvoidNode; Nif::NIFFile file("test.nif"); @@ -960,8 +944,8 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_child_node_with_empty_data_should_return_shape_with_null_collision_shape) { mNiTriShape.data = Nif::NiGeometryDataPtr(nullptr); - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -979,8 +963,8 @@ namespace { auto data = static_cast(mNiTriShape.data.getPtr()); data->mTriangles.clear(); - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -999,8 +983,8 @@ namespace mNiStringExtraData.mData = "NCC__"; mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData); - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -1028,8 +1012,8 @@ namespace mNiStringExtraData2.mData = "NCC__"; mNiStringExtraData2.recType = Nif::RC_NiStringExtraData; mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData); - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -1055,8 +1039,8 @@ namespace mNiStringExtraData.mData = "NC___"; mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData); - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -1083,8 +1067,8 @@ namespace mNiStringExtraData2.mData = "NC___"; mNiStringExtraData2.recType = Nif::RC_NiStringExtraData; mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData); - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -1112,13 +1096,13 @@ namespace init(emptyCollisionNode); niTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData); - niTriShape.parents.push_back(&mNiNode); + niTriShape.mParents.push_back(&mNiNode); emptyCollisionNode.recType = Nif::RC_RootCollisionNode; - emptyCollisionNode.parents.push_back(&mNiNode); + emptyCollisionNode.mParents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList( - std::vector({ Nif::NodePtr(&niTriShape), Nif::NodePtr(&emptyCollisionNode) })); + mNiNode.mChildren + = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&niTriShape), Nif::NiAVObjectPtr(&emptyCollisionNode) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -1144,8 +1128,8 @@ namespace mNiStringExtraData.mData = "MRK"; mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData); - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -1163,9 +1147,9 @@ namespace mNiIntegerExtraData.mData = 32; // BSX flag "editor marker" mNiIntegerExtraData.recType = Nif::RC_BSXFlags; mNiTriShape.mExtraList.push_back(Nif::ExtraPtr(&mNiIntegerExtraData)); - mNiTriShape.parents.push_back(&mNiNode); + mNiTriShape.mParents.push_back(&mNiNode); mNiTriShape.mName = "EditorMarker"; - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("test.nif"); file.mRoots.push_back(&mNiNode); @@ -1184,11 +1168,11 @@ namespace mNiStringExtraData.mData = "MRK"; mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData); - mNiTriShape.parents.push_back(&mNiNode2); - mNiNode2.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode2); + mNiNode2.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; mNiNode2.recType = Nif::RC_RootCollisionNode; - mNiNode2.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiNode2) })); + mNiNode2.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiNode2) }; mNiNode.recType = Nif::RC_NiNode; Nif::NIFFile file("test.nif"); @@ -1290,8 +1274,8 @@ namespace TEST_F(TestBulletNifLoader, for_avoid_collision_mesh_should_ignore_tri_strips_data_with_less_than_3_strips) { - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; mNiNode.recType = Nif::RC_AvoidNode; mNiTriStripsData.mStrips.front() = { 0, 1 }; @@ -1309,8 +1293,8 @@ namespace TEST_F(TestBulletNifLoader, for_animated_mesh_should_ignore_tri_strips_data_with_less_than_3_strips) { mNiTriStripsData.mStrips.front() = { 0, 1 }; - mNiTriStrips.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriStrips) })); + mNiTriStrips.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriStrips) }; Nif::NIFFile file("xtest.nif"); file.mRoots.push_back(&mNiNode); @@ -1326,8 +1310,8 @@ namespace TEST_F(TestBulletNifLoader, should_not_add_static_mesh_with_no_triangles_to_compound_shape) { mNiTriStripsData.mStrips.front() = { 0, 1 }; - mNiTriShape.parents.push_back(&mNiNode); - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); + mNiTriShape.mParents.push_back(&mNiNode); + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; Nif::NIFFile file("xtest.nif"); file.mRoots.push_back(&mNiNode); @@ -1351,13 +1335,13 @@ namespace TEST_F(TestBulletNifLoader, should_handle_node_with_multiple_parents) { - copy(mTransform, mNiTriShape.trafo); - mNiTriShape.trafo.mScale = 4; - mNiTriShape.parents = { &mNiNode, &mNiNode2 }; - mNiNode.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); - mNiNode.trafo.mScale = 2; - mNiNode2.children = Nif::NodeList(std::vector({ Nif::NodePtr(&mNiTriShape) })); - mNiNode2.trafo.mScale = 3; + copy(mTransform, mNiTriShape.mTransform); + mNiTriShape.mTransform.mScale = 4; + mNiTriShape.mParents = { &mNiNode, &mNiNode2 }; + mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; + mNiNode.mTransform.mScale = 2; + mNiNode2.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) }; + mNiNode2.mTransform.mScale = 3; Nif::NIFFile file("xtest.nif"); file.mRoots.push_back(&mNiNode); diff --git a/apps/openmw_test_suite/nifosg/testnifloader.cpp b/apps/openmw_test_suite/nifosg/testnifloader.cpp index 6bcef223d9..a8b9e2fd09 100644 --- a/apps/openmw_test_suite/nifosg/testnifloader.cpp +++ b/apps/openmw_test_suite/nifosg/testnifloader.cpp @@ -66,7 +66,7 @@ namespace TEST_F(NifOsgLoaderTest, shouldLoadFileWithDefaultNode) { - Nif::Node node; + Nif::NiAVObject node; init(node); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&node); @@ -183,14 +183,14 @@ osg::Group { TEST_P(NifOsgLoaderBSShaderPrefixTest, shouldAddShaderPrefix) { - Nif::Node node; + Nif::NiAVObject node; init(node); Nif::BSShaderPPLightingProperty property; property.recType = Nif::RC_BSShaderPPLightingProperty; property.textureSet = nullptr; property.mController = nullptr; property.type = GetParam().mShaderType; - node.props.push_back(Nif::RecordPtrT(&property)); + node.mProperties.push_back(Nif::RecordPtrT(&property)); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&node); auto result = Loader::load(file, &mImageManager); @@ -211,14 +211,14 @@ osg::Group { TEST_P(NifOsgLoaderBSLightingShaderPrefixTest, shouldAddShaderPrefix) { - Nif::Node node; + Nif::NiAVObject node; init(node); Nif::BSLightingShaderProperty property; property.recType = Nif::RC_BSLightingShaderProperty; property.mTextureSet = nullptr; property.mController = nullptr; property.type = GetParam().mShaderType; - node.props.push_back(Nif::RecordPtrT(&property)); + node.mProperties.push_back(Nif::RecordPtrT(&property)); Nif::NIFFile file("test.nif"); file.mRoots.push_back(&node); auto result = Loader::load(file, &mImageManager); diff --git a/components/nif/controller.cpp b/components/nif/controller.cpp index 1355ce21d3..a3d7f33e45 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -308,7 +308,7 @@ namespace Nif { NiInterpController::read(nif); size_t numTargets = nif->getUShort(); - std::vector targets; + std::vector targets; targets.resize(numTargets); for (size_t i = 0; i < targets.size(); i++) targets[i].read(nif); diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index d194ea3060..68e795e7fc 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -160,7 +160,7 @@ namespace Nif osg::Vec3f offsetRandom; - NodePtr emitter; + NiAVObjectPtr emitter; int numParticles; int activeCount; @@ -211,7 +211,7 @@ namespace Nif struct NiLookAtController : public Controller { - NodePtr target; + NiAVObjectPtr target; unsigned short lookAtFlags{ 0 }; void read(NIFStream* nif) override; @@ -237,7 +237,7 @@ namespace Nif struct NiMultiTargetTransformController : public NiInterpController { - NodeList mExtraTargets; + NiAVObjectList mExtraTargets; void read(NIFStream* nif) override; void post(Reader& nif) override; diff --git a/components/nif/data.hpp b/components/nif/data.hpp index d81f6de22f..849cbde7bd 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -229,8 +229,8 @@ namespace Nif { NiSkinDataPtr mData; NiSkinPartitionPtr mPartitions; - NodePtr mRoot; - NodeList mBones; + NiAVObjectPtr mRoot; + NiAVObjectList mBones; void read(NIFStream* nif) override; void post(Reader& nif) override; diff --git a/components/nif/effect.cpp b/components/nif/effect.cpp index 36407f8dc2..8db6de06d4 100644 --- a/components/nif/effect.cpp +++ b/components/nif/effect.cpp @@ -8,7 +8,7 @@ namespace Nif void NiDynamicEffect::read(NIFStream* nif) { - Node::read(nif); + NiAVObject::read(nif); if (nif->getVersion() > NIFFile::VER_MW && nif->getVersion() < nif->generateVersion(10, 1, 0, 0)) return; diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index 06f85cd5d5..906a7fdedf 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -30,7 +30,7 @@ namespace Nif { // Abstract - struct NiDynamicEffect : public Node + struct NiDynamicEffect : public NiAVObject { bool mSwitchState{ true }; void read(NIFStream* nif) override; diff --git a/components/nif/node.cpp b/components/nif/node.cpp index fba0e1a69a..010a363436 100644 --- a/components/nif/node.cpp +++ b/components/nif/node.cpp @@ -75,51 +75,47 @@ namespace Nif } } - void Node::read(NIFStream* nif) + void NiAVObject::read(NIFStream* nif) { NiObjectNET::read(nif); - flags = nif->getBethVersion() <= 26 ? nif->getUShort() : nif->getUInt(); - nif->read(trafo.mTranslation); - nif->read(trafo.mRotation); - nif->read(trafo.mScale); - + if (nif->getBethVersion() <= 26) + mFlags = nif->get(); + else + nif->read(mFlags); + nif->read(mTransform.mTranslation); + nif->read(mTransform.mRotation); + nif->read(mTransform.mScale); if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0)) - velocity = nif->getVector3(); + nif->read(mVelocity); if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3) - readRecordList(nif, props); - - if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0)) - hasBounds = nif->getBoolean(); - if (hasBounds) - bounds.read(nif); - // Reference to the collision object in Gamebryo files. + readRecordList(nif, mProperties); + if (nif->getVersion() <= NIFStream::generateVersion(4, 2, 2, 0) && nif->get()) + mBounds.read(nif); if (nif->getVersion() >= NIFStream::generateVersion(10, 0, 1, 0)) - collision.read(nif); - - parents.clear(); - - isBone = false; + mCollision.read(nif); } - void Node::post(Reader& nif) + void NiAVObject::post(Reader& nif) { NiObjectNET::post(nif); - postRecordList(nif, props); - collision.post(nif); + + postRecordList(nif, mProperties); + mCollision.post(nif); } - void Node::setBone() + void NiAVObject::setBone() { - isBone = true; + mIsBone = true; } void NiNode::read(NIFStream* nif) { - Node::read(nif); - readRecordList(nif, children); + NiAVObject::read(nif); + + readRecordList(nif, mChildren); if (nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO4) - readRecordList(nif, effects); + readRecordList(nif, mEffects); // FIXME: stopgap solution until we figure out what Oblivion does if it does anything if (nif->getVersion() > NIFFile::NIFVersion::VER_MW && nif->getVersion() < NIFFile::NIFVersion::VER_BGS) @@ -131,23 +127,24 @@ namespace Nif // FIXME: if node 0 is *not* the only root node, this must not happen. // FIXME: doing this here is awful. // We want to do this on world scene graph level rather than local scene graph level. - if (0 == recIndex && !Misc::StringUtils::ciEqual(mName, "bip01")) + if (recIndex == 0 && !Misc::StringUtils::ciEqual(mName, "bip01")) { - trafo = Nif::NiTransform::getIdentity(); + mTransform = Nif::NiTransform::getIdentity(); } } void NiNode::post(Reader& nif) { - Node::post(nif); - postRecordList(nif, children); - postRecordList(nif, effects); + NiAVObject::post(nif); + + postRecordList(nif, mChildren); + postRecordList(nif, mEffects); - for (auto& child : children) + for (auto& child : mChildren) { // Why would a unique list of children contain empty refs? if (!child.empty()) - child->parents.push_back(this); + child->mParents.push_back(this); } } @@ -171,7 +168,7 @@ namespace Nif void NiGeometry::read(NIFStream* nif) { - Node::read(nif); + NiAVObject::read(nif); data.read(nif); skin.read(nif); material.read(nif); @@ -185,7 +182,7 @@ namespace Nif void NiGeometry::post(Reader& nif) { - Node::post(nif); + NiAVObject::post(nif); data.post(nif); skin.post(nif); shaderprop.post(nif); @@ -224,7 +221,7 @@ namespace Nif void NiCamera::read(NIFStream* nif) { - Node::read(nif); + NiAVObject::read(nif); cam.read(nif); @@ -290,7 +287,7 @@ namespace Nif if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) mMode = nif->getUShort() & 0x7; else - mMode = (flags >> 5) & 0x3; + mMode = (mFlags >> 5) & 0x3; } void NiDefaultAVObjectPalette::read(NIFStream* nif) @@ -338,7 +335,7 @@ namespace Nif void BSTriShape::read(NIFStream* nif) { - Node::read(nif); + NiAVObject::read(nif); nif->read(mBoundingSphere); if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_F76) @@ -392,7 +389,7 @@ namespace Nif void BSTriShape::post(Reader& nif) { - Node::post(nif); + NiAVObject::post(nif); mSkin.post(nif); mShaderProperty.post(nif); mAlphaProperty.post(nif); diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 2a1fcd9af6..76651b05db 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -51,7 +51,7 @@ namespace Nif osg::Vec3f origin; }; - unsigned int type; + unsigned int type{ BASE_BV }; osg::BoundingSpheref sphere; NiBoxBV box; NiCapsuleBV capsule; @@ -66,11 +66,9 @@ namespace Nif { }; - /** A Node is an object that's part of the main NIF tree. It has - parent node (unless it's the root), and transformation (location - and rotation) relative to it's parent. - */ - struct Node : public NiObjectNET + // 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. + struct NiAVObject : public NiObjectNET { enum Flags { @@ -80,57 +78,48 @@ namespace Nif Flag_ActiveCollision = 0x0020 }; - // Node flags. Interpretation depends somewhat on the type of node. - unsigned int flags; - - NiTransform trafo; - osg::Vec3f velocity; // Unused? Might be a run-time game state - PropertyList props; - - // Bounding box info - bool hasBounds{ false }; - NiBoundingVolume bounds; - - // Collision object info - NiCollisionObjectPtr collision; + // Node flags. Interpretation depends on the record type. + uint32_t mFlags; + NiTransform mTransform; + osg::Vec3f mVelocity; + PropertyList mProperties; + NiBoundingVolume mBounds; + NiCollisionObjectPtr mCollision; + // Parent nodes for the node. Only types derived from NiNode can be parents. + std::vector mParents; + bool mIsBone{ false }; void read(NIFStream* nif) override; void post(Reader& nif) override; - // Parent node, or nullptr for the root node. As far as I'm aware, only - // NiNodes (or types derived from NiNodes) can be parents. - std::vector parents; - - bool isBone{ false }; - void setBone(); - - bool isHidden() const { return flags & Flag_Hidden; } - bool hasMeshCollision() const { return flags & Flag_MeshCollision; } - bool hasBBoxCollision() const { return flags & Flag_BBoxCollision; } - bool collisionActive() const { return flags & Flag_ActiveCollision; } + bool isHidden() const { return mFlags & Flag_Hidden; } + bool hasMeshCollision() const { return mFlags & Flag_MeshCollision; } + bool hasBBoxCollision() const { return mFlags & Flag_BBoxCollision; } + bool collisionActive() const { return mFlags & Flag_ActiveCollision; } }; - struct NiNode : Node + struct NiNode : NiAVObject { - NodeList children; - NodeList effects; - enum BSAnimFlags { AnimFlag_AutoPlay = 0x0020 }; + enum BSParticleFlags { ParticleFlag_AutoPlay = 0x0020, ParticleFlag_LocalSpace = 0x0080 }; + NiAVObjectList mChildren; + NiAVObjectList mEffects; + void read(NIFStream* nif) override; void post(Reader& nif) override; }; - struct NiGeometry : Node + struct NiGeometry : NiAVObject { /* Possible flags: 0x40 - mesh has no vertex normals ? @@ -176,7 +165,7 @@ namespace Nif { }; - struct NiCamera : Node + struct NiCamera : NiAVObject { struct Camera { @@ -234,7 +223,7 @@ namespace Nif void read(NIFStream* nif) override; - bool swing() const { return flags & Flag_Swing; } + bool swing() const { return mFlags & Flag_Swing; } }; // Abstract @@ -276,8 +265,8 @@ namespace Nif struct NiDefaultAVObjectPalette : Record { - NodePtr mScene; - std::unordered_map mObjects; + NiAVObjectPtr mScene; + std::unordered_map mObjects; void read(NIFStream* nif) override; void post(Reader& nif) override; @@ -285,7 +274,7 @@ namespace Nif struct BSTreeNode : NiNode { - NodeList mBones1, mBones2; + NiAVObjectList mBones1, mBones2; void read(NIFStream* nif) override; void post(Reader& nif) override; }; @@ -350,7 +339,7 @@ namespace Nif void read(NIFStream* nif, uint16_t flags); }; - struct BSTriShape : Node + struct BSTriShape : NiAVObject { osg::BoundingSpheref mBoundingSphere; std::array mBoundMinMax; @@ -397,5 +386,6 @@ namespace Nif void read(NIFStream* nif) override; }; -} // Namespace + +} #endif diff --git a/components/nif/physics.hpp b/components/nif/physics.hpp index a7bfa1425d..7c7c3df21e 100644 --- a/components/nif/physics.hpp +++ b/components/nif/physics.hpp @@ -374,7 +374,7 @@ namespace Nif struct NiCollisionObject : public Record { // The node that references this object - NodePtr mTarget; + NiAVObjectPtr mTarget; void read(NIFStream* nif) override { mTarget.read(nif); } void post(Reader& nif) override { mTarget.post(nif); } @@ -541,7 +541,7 @@ namespace Nif struct bhkCompressedMeshShape : public bhkShape { - NodePtr mTarget; + NiAVObjectPtr mTarget; uint32_t mUserData; float mRadius; osg::Vec4f mScale; diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index eb704dbc21..9f75b31d74 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -110,7 +110,7 @@ namespace Nif value.post(nif); } - struct Node; + struct NiAVObject; struct Extra; struct Property; struct NiUVData; @@ -152,7 +152,7 @@ namespace Nif struct BSMultiBound; struct BSMultiBoundData; - using NodePtr = RecordPtrT; + using NiAVObjectPtr = RecordPtrT; using ExtraPtr = RecordPtrT; using NiUVDataPtr = RecordPtrT; using NiPosDataPtr = RecordPtrT; @@ -190,7 +190,7 @@ namespace Nif using BSMultiBoundPtr = RecordPtrT; using BSMultiBoundDataPtr = RecordPtrT; - using NodeList = RecordListT; + using NiAVObjectList = RecordListT; using PropertyList = RecordListT; using ExtraList = RecordListT; using NiSourceTextureList = RecordListT; diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 31be54b030..bc207e52bf 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -132,13 +132,13 @@ namespace NifBullet mShape->mFileHash = nif.getHash(); const size_t numRoots = nif.numRoots(); - std::vector roots; + std::vector roots; for (size_t i = 0; i < numRoots; ++i) { const Nif::Record* r = nif.getRoot(i); if (!r) continue; - const Nif::Node* node = dynamic_cast(r); + const Nif::NiAVObject* node = dynamic_cast(r); if (node) roots.emplace_back(node); } @@ -151,7 +151,7 @@ namespace NifBullet } // Try to find a valid bounding box first. If one's found for any root node, use that. - for (const Nif::Node* node : roots) + for (const Nif::NiAVObject* node : roots) { if (findBoundingBox(*node, filename)) { @@ -175,15 +175,19 @@ namespace NifBullet // If there's no bounding box, we'll have to generate a Bullet collision shape // from the collision data present in every root node. - for (const Nif::Node* node : roots) + for (const Nif::NiAVObject* node : roots) { - bool hasCollisionNode = hasRootCollisionNode(*node); - bool hasCollisionShape = hasCollisionNode && !collisionShapeIsEmpty(*node); - if (hasCollisionNode && !hasCollisionShape) - mShape->mVisualCollisionType = Resource::VisualCollisionType::Camera; - bool generateCollisionShape = !hasCollisionShape; + const Nif::NiNode* colNode = findRootCollisionNode(*node); + bool hasCollisionShape = false; + if (colNode != nullptr) + { + if (colNode->mBounds.type == Nif::NiBoundingVolume::Type::BASE_BV && !colNode->mChildren.empty()) + hasCollisionShape = true; + else + mShape->mVisualCollisionType = Resource::VisualCollisionType::Camera; + } HandleNodeArgs args; - args.mAutogenerated = args.mIsCollisionNode = generateCollisionShape; + args.mAutogenerated = args.mIsCollisionNode = !hasCollisionShape; args.mAnimated = isAnimated; handleNode(filename, *node, nullptr, args, mShape->mVisualCollisionType); } @@ -199,79 +203,53 @@ namespace NifBullet // Find a boundingBox in the node hierarchy. // Return: use bounding box for collision? - bool BulletNifLoader::findBoundingBox(const Nif::Node& node, const std::string& filename) + bool BulletNifLoader::findBoundingBox(const Nif::NiAVObject& node, const std::string& filename) { - if (node.hasBounds) + unsigned int type = node.mBounds.type; + switch (type) { - unsigned int type = node.bounds.type; - switch (type) - { - case Nif::NiBoundingVolume::Type::BOX_BV: - mShape->mCollisionBox.mExtents = node.bounds.box.extents; - mShape->mCollisionBox.mCenter = node.bounds.box.center; - break; - default: - { - std::stringstream warning; - warning << "Unsupported NiBoundingVolume type " << type << " in node " << node.recIndex; - warning << " in file " << filename; - warn(warning.str()); - } - } - - if (node.hasBBoxCollision()) + case Nif::NiBoundingVolume::Type::BASE_BV: + break; + case Nif::NiBoundingVolume::Type::BOX_BV: + mShape->mCollisionBox.mExtents = node.mBounds.box.extents; + mShape->mCollisionBox.mCenter = node.mBounds.box.center; + break; + default: { - return true; + std::stringstream warning; + warning << "Unsupported NiBoundingVolume type " << type << " in node " << node.recIndex; + warning << " in file " << filename; + warn(warning.str()); } } + if (type != Nif::NiBoundingVolume::Type::BASE_BV && node.hasBBoxCollision()) + return true; + if (const Nif::NiNode* ninode = dynamic_cast(&node)) { - const Nif::NodeList& list = ninode->children; - for (const auto& child : list) + for (const auto& child : ninode->mChildren) if (!child.empty() && findBoundingBox(child.get(), filename)) return true; } return false; } - bool BulletNifLoader::hasRootCollisionNode(const Nif::Node& rootNode) const - { - if (const Nif::NiNode* ninode = dynamic_cast(&rootNode)) - { - for (const auto& child : ninode->children) - { - if (child.empty()) - continue; - if (child.getPtr()->recType == Nif::RC_RootCollisionNode) - return true; - } - } - return false; - } - - bool BulletNifLoader::collisionShapeIsEmpty(const Nif::Node& rootNode) const + const Nif::NiNode* BulletNifLoader::findRootCollisionNode(const Nif::NiAVObject& rootNode) const { if (const Nif::NiNode* ninode = dynamic_cast(&rootNode)) { - for (const auto& child : ninode->children) + for (const auto& child : ninode->mChildren) { - if (child.empty()) - continue; - const Nif::Node* childNode = child.getPtr(); - if (childNode->recType != Nif::RC_RootCollisionNode) - continue; - const Nif::NiNode* niChildnode - = static_cast(childNode); // RootCollisionNode is always a NiNode - if (childNode->hasBounds || niChildnode->children.size() > 0) - return false; + if (!child.empty() && child.getPtr()->recType == Nif::RC_RootCollisionNode) + return static_cast(child.getPtr()); } } - return true; + return nullptr; } - void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node& node, const Nif::Parent* parent, - HandleNodeArgs args, Resource::VisualCollisionType& visualCollisionType) + void BulletNifLoader::handleNode(const std::string& fileName, const Nif::NiAVObject& node, + const Nif::Parent* parent, HandleNodeArgs args, Resource::VisualCollisionType& visualCollisionType) { // TODO: allow on-the fly collision switching via toggling this flag if (node.recType == Nif::RC_NiCollisionSwitch && !node.collisionActive()) @@ -354,10 +332,10 @@ namespace NifBullet if (args.mIsCollisionNode) { - // NOTE: a trishape with hasBounds=true, 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. // (occurs in tr_ex_imp_wall_arch_04.nif) - if (!node.hasBounds + if (node.mBounds.type == Nif::NiBoundingVolume::Type::BASE_BV && (node.recType == Nif::RC_NiTriShape || node.recType == Nif::RC_NiTriStrips || node.recType == Nif::RC_BSLODTriShape)) { @@ -368,14 +346,13 @@ namespace NifBullet // For NiNodes, loop through children if (const Nif::NiNode* ninode = dynamic_cast(&node)) { - const Nif::NodeList& list = ninode->children; const Nif::Parent currentParent{ *ninode, parent }; - for (const auto& child : list) + for (const auto& child : ninode->mChildren) { if (child.empty()) continue; - assert(std::find(child->parents.begin(), child->parents.end(), ninode) != child->parents.end()); + assert(std::find(child->mParents.begin(), child->mParents.end(), ninode) != child->mParents.end()); handleNode(fileName, child.get(), ¤tParent, args, visualCollisionType); } } @@ -403,9 +380,9 @@ namespace NifBullet auto childShape = std::make_unique(childMesh.get(), true); std::ignore = childMesh.release(); - osg::Matrixf transform = niGeometry.trafo.toMatrix(); + osg::Matrixf transform = niGeometry.mTransform.toMatrix(); for (const Nif::Parent* parent = nodeParent; parent != nullptr; parent = parent->mParent) - transform *= parent->mNiNode.trafo.toMatrix(); + transform *= parent->mNiNode.mTransform.toMatrix(); childShape->setLocalScaling(Misc::Convert::toBullet(transform.getScale())); transform.orthoNormalize(transform); diff --git a/components/nifbullet/bulletnifloader.hpp b/components/nifbullet/bulletnifloader.hpp index c70eb997fa..819ba34b34 100644 --- a/components/nifbullet/bulletnifloader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -22,10 +22,8 @@ class btCollisionShape; namespace Nif { - struct Node; - struct Transformation; - struct NiTriShape; - struct NiTriStrips; + struct NiAVObject; + struct NiNode; struct NiGeometry; struct Parent; } @@ -50,7 +48,7 @@ namespace NifBullet osg::ref_ptr load(Nif::FileView file); private: - bool findBoundingBox(const Nif::Node& node, const std::string& filename); + bool findBoundingBox(const Nif::NiAVObject& node, const std::string& filename); struct HandleNodeArgs { @@ -61,11 +59,10 @@ namespace NifBullet bool mAvoid{ false }; }; - void handleNode(const std::string& fileName, const Nif::Node& node, const Nif::Parent* parent, + void handleNode(const std::string& fileName, const Nif::NiAVObject& node, const Nif::Parent* parent, HandleNodeArgs args, Resource::VisualCollisionType& visualCollisionType); - bool hasRootCollisionNode(const Nif::Node& rootNode) const; - bool collisionShapeIsEmpty(const Nif::Node& rootNode) const; + const Nif::NiNode* findRootCollisionNode(const Nif::NiAVObject& rootNode) const; void handleNiTriShape(const Nif::NiGeometry& nifNode, const Nif::Parent* parent, HandleNodeArgs args); diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 1a595a3ab5..9683de9a23 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -76,12 +76,12 @@ namespace void apply(osg::Drawable& node) override { traverse(node); } }; - void getAllNiNodes(const Nif::Node* node, std::vector& outIndices) + void getAllNiNodes(const Nif::NiAVObject* node, std::vector& outIndices) { if (const Nif::NiNode* ninode = dynamic_cast(node)) { outIndices.push_back(ninode->recIndex); - for (const auto& child : ninode->children) + for (const auto& child : ninode->mChildren) if (!child.empty()) getAllNiNodes(child.getPtr(), outIndices); } @@ -103,11 +103,11 @@ namespace // Collect all properties affecting the given drawable that should be handled on drawable basis rather than on the // node hierarchy above it. void collectDrawableProperties( - const Nif::Node* nifNode, const Nif::Parent* parent, std::vector& out) + const Nif::NiAVObject* nifNode, const Nif::Parent* parent, std::vector& out) { if (parent != nullptr) collectDrawableProperties(&parent->mNiNode, parent->mParent, out); - for (const auto& property : nifNode->props) + for (const auto& property : nifNode->mProperties) { if (!property.empty()) { @@ -345,13 +345,13 @@ namespace NifOsg osg::ref_ptr load(Nif::FileView nif, Resource::ImageManager* imageManager) { const size_t numRoots = nif.numRoots(); - std::vector roots; + std::vector roots; for (size_t i = 0; i < numRoots; ++i) { const Nif::Record* r = nif.getRoot(i); if (!r) continue; - const Nif::Node* nifNode = dynamic_cast(r); + const Nif::NiAVObject* nifNode = dynamic_cast(r); if (nifNode) roots.emplace_back(nifNode); } @@ -362,7 +362,7 @@ namespace NifOsg osg::ref_ptr created(new osg::Group); created->setDataVariance(osg::Object::STATIC); - for (const Nif::Node* root : roots) + for (const Nif::NiAVObject* root : roots) { auto node = handleNode(root, nullptr, nullptr, { .mNifVersion = nif.getVersion(), @@ -397,13 +397,13 @@ namespace NifOsg return created; } - void applyNodeProperties(const Nif::Node* nifNode, osg::Node* applyTo, + void applyNodeProperties(const Nif::NiAVObject* nifNode, osg::Node* applyTo, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector& boundTextures, int animflags) { bool hasStencilProperty = false; - for (const auto& property : nifNode->props) + for (const auto& property : nifNode->mProperties) { if (property.empty()) continue; @@ -420,13 +420,13 @@ namespace NifOsg } } - for (const auto& property : nifNode->props) + for (const auto& property : nifNode->mProperties) { if (!property.empty()) { // Get the lowest numbered recIndex of the NiTexturingProperty root node. // This is what is overridden when a spell effect "particle texture" is used. - if (nifNode->parents.empty() && !mFoundFirstRootTexturingProperty + if (nifNode->mParents.empty() && !mFoundFirstRootTexturingProperty && property.getPtr()->recType == Nif::RC_NiTexturingProperty) { mFirstRootTextureIndex = property.getPtr()->recIndex; @@ -482,23 +482,23 @@ namespace NifOsg return switchNode; } - static osg::ref_ptr prepareSequenceNode(const Nif::Node* nifNode) + static osg::ref_ptr prepareSequenceNode(const Nif::NiAVObject* nifNode) { const Nif::NiFltAnimationNode* niFltAnimationNode = static_cast(nifNode); osg::ref_ptr sequenceNode(new osg::Sequence); sequenceNode->setName(niFltAnimationNode->mName); - if (!niFltAnimationNode->children.empty()) + if (!niFltAnimationNode->mChildren.empty()) { if (niFltAnimationNode->swing()) sequenceNode->setDefaultTime( - niFltAnimationNode->mDuration / (niFltAnimationNode->children.size() * 2)); + niFltAnimationNode->mDuration / (niFltAnimationNode->mChildren.size() * 2)); else - sequenceNode->setDefaultTime(niFltAnimationNode->mDuration / niFltAnimationNode->children.size()); + sequenceNode->setDefaultTime(niFltAnimationNode->mDuration / niFltAnimationNode->mChildren.size()); } return sequenceNode; } - static void activateSequenceNode(osg::Group* osgNode, const Nif::Node* nifNode) + static void activateSequenceNode(osg::Group* osgNode, const Nif::NiAVObject* nifNode) { const Nif::NiFltAnimationNode* niFltAnimationNode = static_cast(nifNode); osg::Sequence* sequenceNode = static_cast(osgNode); @@ -535,7 +535,7 @@ namespace NifOsg texture->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE); } - bool handleEffect(const Nif::Node* nifNode, osg::StateSet* stateset, Resource::ImageManager* imageManager) + bool handleEffect(const Nif::NiAVObject* nifNode, osg::StateSet* stateset, Resource::ImageManager* imageManager) { if (nifNode->recType != Nif::RC_NiTextureEffect) { @@ -596,7 +596,7 @@ namespace NifOsg } // Get a default dataVariance for this node to be used as a hint by optimization (post)routines - osg::ref_ptr createNode(const Nif::Node* nifNode) + osg::ref_ptr createNode(const Nif::NiAVObject* nifNode) { osg::ref_ptr node; osg::Object::DataVariance dataVariance = osg::Object::UNSPECIFIED; @@ -611,15 +611,15 @@ namespace NifOsg // This takes advantage of the fact root nodes can't have additional controllers // loaded from an external .kf file (original engine just throws "can't find node" errors if you // try). - if (nifNode->parents.empty() && nifNode->mController.empty() && nifNode->trafo.isIdentity()) + if (nifNode->mParents.empty() && nifNode->mController.empty() && nifNode->mTransform.isIdentity()) node = new osg::Group; - dataVariance = nifNode->isBone ? osg::Object::DYNAMIC : osg::Object::STATIC; + dataVariance = nifNode->mIsBone ? osg::Object::DYNAMIC : osg::Object::STATIC; break; } if (!node) - node = new NifOsg::MatrixTransform(nifNode->trafo); + node = new NifOsg::MatrixTransform(nifNode->mTransform); node->setDataVariance(dataVariance); @@ -627,7 +627,7 @@ namespace NifOsg } osg::ref_ptr handleNode( - const Nif::Node* nifNode, const Nif::Parent* parent, osg::Group* parentNode, HandleNodeArgs args) + const Nif::NiAVObject* nifNode, const Nif::Parent* parent, osg::Group* parentNode, HandleNodeArgs args) { if (args.mRootNode && Misc::StringUtils::ciEqual(nifNode->mName, "Bounding Box")) return nullptr; @@ -692,7 +692,7 @@ namespace NifOsg } if (nifNode->recType == Nif::RC_NiBSAnimationNode || nifNode->recType == Nif::RC_NiBSParticleNode) - args.mAnimFlags = nifNode->flags; + args.mAnimFlags = nifNode->mFlags; if (nifNode->recType == Nif::RC_NiSortAdjustNode) { @@ -829,7 +829,7 @@ namespace NifOsg const Nif::NiNode* ninode = dynamic_cast(nifNode); if (ninode) { - const Nif::NodeList& children = ninode->children; + const Nif::NiAVObjectList& children = ninode->mChildren; const Nif::Parent currentParent{ *ninode, parent }; for (const auto& child : children) if (!child.empty()) @@ -838,7 +838,7 @@ namespace NifOsg // Propagate effects to the the direct subgraph instead of the node itself // This simulates their "affected node list" which Morrowind appears to replace with the subgraph (?) // Note that the serialized affected node list is actually unused - for (const auto& effect : ninode->effects) + for (const auto& effect : ninode->mEffects) if (!effect.empty()) { osg::ref_ptr effectStateSet = new osg::StateSet; @@ -854,7 +854,7 @@ namespace NifOsg return node; } - void handleMeshControllers(const Nif::Node* nifNode, osg::Node* node, + void handleMeshControllers(const Nif::NiAVObject* nifNode, osg::Node* node, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) { @@ -883,7 +883,7 @@ namespace NifOsg } } - void handleNodeControllers(const Nif::Node* nifNode, osg::Node* node, int animflags, bool& isAnimated) + void handleNodeControllers(const Nif::NiAVObject* nifNode, osg::Node* node, int animflags, bool& isAnimated) { for (Nif::ControllerPtr ctrl = nifNode->mController; !ctrl.empty(); ctrl = ctrl->next) { @@ -1121,7 +1121,7 @@ namespace NifOsg // Load the initial state of the particle system, i.e. the initial particles and their positions, velocity and // colors. void handleParticleInitialState( - const Nif::Node* nifNode, ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl) + const Nif::NiAVObject* nifNode, ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl) { auto particleNode = static_cast(nifNode); if (particleNode->data.empty() || particleNode->data->recType != Nif::RC_NiParticlesData) @@ -1247,7 +1247,7 @@ namespace NifOsg mEmitterQueue.clear(); } - void handleParticleSystem(const Nif::Node* nifNode, const Nif::Parent* parent, osg::Group* parentNode, + void handleParticleSystem(const Nif::NiAVObject* nifNode, const Nif::Parent* parent, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, int animflags) { osg::ref_ptr partsys(new ParticleSystem); @@ -1375,7 +1375,7 @@ namespace NifOsg } } - void handleNiGeometry(const Nif::Node* nifNode, const Nif::Parent* parent, osg::Geometry* geometry, + void handleNiGeometry(const Nif::NiAVObject* nifNode, const Nif::Parent* parent, osg::Geometry* geometry, osg::Node* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) { @@ -1474,7 +1474,7 @@ namespace NifOsg applyDrawableProperties(parentNode, drawableProps, composite, !niGeometryData->mColors.empty(), animflags); } - void handleGeometry(const Nif::Node* nifNode, const Nif::Parent* parent, osg::Group* parentNode, + void handleGeometry(const Nif::NiAVObject* nifNode, const Nif::Parent* parent, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) { @@ -1530,7 +1530,7 @@ namespace NifOsg return morphGeom; } - void handleSkinnedGeometry(const Nif::Node* nifNode, const Nif::Parent* parent, osg::Group* parentNode, + void handleSkinnedGeometry(const Nif::NiAVObject* nifNode, const Nif::Parent* parent, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) { @@ -1548,7 +1548,7 @@ namespace NifOsg const Nif::NiSkinInstance* skin = static_cast(nifNode)->skin.getPtr(); const Nif::NiSkinData* data = skin->mData.getPtr(); - const Nif::NodeList& bones = skin->mBones; + const Nif::NiAVObjectList& bones = skin->mBones; for (std::size_t i = 0; i < bones.size(); ++i) { std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->mName);