Improve node record consistency with NifTools

macos_ci_fix
Alexei Kotov 1 year ago
parent bff9231c3b
commit eb8242946a

@ -415,7 +415,7 @@ 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3); mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3); mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
@ -439,7 +439,7 @@ 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3); mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3); mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
mNode.mParents.push_back(&mNiNode); mNode.mParents.push_back(&mNiNode);
@ -466,12 +466,12 @@ 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3); mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
mNode.mBounds.mBox.mCenter = 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNiNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNiNode.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6); mNiNode.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6);
mNiNode.mBounds.mBox.mCenter = 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) };
@ -497,17 +497,17 @@ 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3); mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
mNode.mBounds.mBox.mCenter = 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNode2.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNode2.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6); mNode2.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6);
mNode2.mBounds.mBox.mCenter = 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNiNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNiNode.mBounds.mBox.mExtents = osg::Vec3f(7, 8, 9); mNiNode.mBounds.mBox.mExtents = osg::Vec3f(7, 8, 9);
mNiNode.mBounds.mBox.mCenter = 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) };
@ -532,18 +532,18 @@ 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3); mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
mNode.mBounds.mBox.mCenter = 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNode2.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNode2.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6); mNode2.mBounds.mBox.mExtents = osg::Vec3f(4, 5, 6);
mNode2.mBounds.mBox.mCenter = 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNiNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNiNode.mBounds.mBox.mExtents = osg::Vec3f(7, 8, 9); mNiNode.mBounds.mBox.mExtents = osg::Vec3f(7, 8, 9);
mNiNode.mBounds.mBox.mCenter = 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) };
@ -568,7 +568,7 @@ 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNode.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3); mNode.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3); mNode.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);
@ -608,7 +608,7 @@ 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.mType = Nif::NiBoundingVolume::Type::BOX_BV; mNiTriShape.mBounds.mType = Nif::BoundingVolume::Type::BOX_BV;
mNiTriShape.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3); mNiTriShape.mBounds.mBox.mExtents = osg::Vec3f(1, 2, 3);
mNiTriShape.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3); mNiTriShape.mBounds.mBox.mCenter = osg::Vec3f(-1, -2, -3);

@ -12,7 +12,7 @@
namespace Nif namespace Nif
{ {
void NiBoundingVolume::read(NIFStream* nif) void BoundingVolume::read(NIFStream* nif)
{ {
nif->read(mType); nif->read(mType);
switch (mType) switch (mType)
@ -55,7 +55,7 @@ namespace Nif
case UNION_BV: case UNION_BV:
{ {
mChildren.resize(nif->get<uint32_t>()); mChildren.resize(nif->get<uint32_t>());
for (NiBoundingVolume& child : mChildren) for (BoundingVolume& child : mChildren)
child.read(nif); child.read(nif);
break; break;
} }
@ -69,7 +69,7 @@ namespace Nif
default: default:
{ {
throw Nif::Exception( throw Nif::Exception(
"Unhandled NiBoundingVolume type: " + std::to_string(mType), nif->getFile().getFilename()); "Unhandled BoundingVolume type: " + std::to_string(mType), nif->getFile().getFilename());
} }
} }
} }
@ -168,7 +168,8 @@ namespace Nif
NiAVObject::read(nif); NiAVObject::read(nif);
mData.read(nif); mData.read(nif);
mSkin.read(nif); if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13))
mSkin.read(nif);
mMaterial.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)
@ -218,7 +219,7 @@ namespace Nif
void BSLODTriShape::read(NIFStream* nif) void BSLODTriShape::read(NIFStream* nif)
{ {
NiTriShape::read(nif); NiTriBasedGeom::read(nif);
nif->readArray(mLOD); nif->readArray(mLOD);
} }
@ -356,7 +357,7 @@ namespace Nif
mMultiBound.read(nif); mMultiBound.read(nif);
if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SKY) if (nif->getBethVersion() >= NIFFile::BethVersion::BETHVER_SKY)
nif->read(mType); mCullingType = static_cast<BSCPCullingType>(nif->get<uint32_t>());
} }
void BSMultiBoundNode::post(Reader& nif) void BSMultiBoundNode::post(Reader& nif)

@ -13,7 +13,7 @@ namespace Nif
struct NiNode; struct NiNode;
struct NiBoundingVolume struct BoundingVolume
{ {
enum Type : uint32_t enum Type : uint32_t
{ {
@ -56,7 +56,7 @@ namespace Nif
NiBoxBV mBox; NiBoxBV mBox;
NiCapsuleBV mCapsule; NiCapsuleBV mCapsule;
NiLozengeBV mLozenge; NiLozengeBV mLozenge;
std::vector<NiBoundingVolume> mChildren; std::vector<BoundingVolume> mChildren;
NiHalfSpaceBV mHalfSpace; NiHalfSpaceBV mHalfSpace;
void read(NIFStream* nif); void read(NIFStream* nif);
@ -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;
@ -152,15 +152,20 @@ namespace Nif
void post(Reader& nif) override; void post(Reader& nif) override;
}; };
struct NiTriShape : NiGeometry // Abstract triangle-based geometry
struct NiTriBasedGeom : NiGeometry
{ {
}; };
struct NiTriStrips : NiGeometry struct NiTriShape : NiTriBasedGeom
{ {
}; };
struct NiLines : NiGeometry struct NiTriStrips : NiTriBasedGeom
{
};
struct NiLines : NiTriBasedGeom
{ {
}; };
@ -168,7 +173,7 @@ namespace Nif
{ {
}; };
struct BSLODTriShape : NiTriShape struct BSLODTriShape : NiTriBasedGeom
{ {
std::array<uint32_t, 3> mLOD; std::array<uint32_t, 3> mLOD;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
@ -283,8 +288,17 @@ namespace Nif
struct BSMultiBoundNode : NiNode struct BSMultiBoundNode : NiNode
{ {
enum class BSCPCullingType : uint32_t
{
Normal,
AllPass,
AllFail,
IgnoreMultiBounds,
ForceMultiBoundsNoUpdate,
};
BSMultiBoundPtr mMultiBound; BSMultiBoundPtr mMultiBound;
uint32_t mType{ 0 }; BSCPCullingType mCullingType;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(Reader& nif) override; void post(Reader& nif) override;

@ -175,7 +175,7 @@ namespace NifBullet
bool hasCollisionShape = false; bool hasCollisionShape = false;
if (colNode != nullptr) if (colNode != nullptr)
{ {
if (colNode->mBounds.mType == 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;
@ -202,22 +202,22 @@ namespace NifBullet
unsigned int type = node.mBounds.mType; 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.mBox.mExtents; mShape->mCollisionBox.mExtents = node.mBounds.mBox.mExtents;
mShape->mCollisionBox.mCenter = node.mBounds.mBox.mCenter; 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))
@ -329,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.mType == 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))
{ {

Loading…
Cancel
Save