mirror of
https://github.com/OpenMW/openmw.git
synced 2025-05-19 21:41:30 +00:00
Merge branch 'boundingboxing' into 'master'
BulletNifLoader: Replicate node bounds handling more closely See merge request OpenMW/openmw!3505
This commit is contained in:
commit
a08ca11c34
2 changed files with 32 additions and 47 deletions
|
@ -411,10 +411,9 @@ namespace
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(
|
TEST_F(TestBulletNifLoader, for_root_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.mName = "Bounding Box";
|
||||||
mNode.mBounds.mType = Nif::BoundingVolume::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);
|
||||||
|
@ -436,9 +435,9 @@ namespace
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader, for_child_nif_node_with_bounding_box)
|
TEST_F(TestBulletNifLoader, for_child_bounding_box_should_return_shape_with_compound_shape_with_box_inside)
|
||||||
{
|
{
|
||||||
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
mNode.mName = "Bounding Box";
|
||||||
mNode.mBounds.mType = Nif::BoundingVolume::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);
|
||||||
|
@ -462,10 +461,9 @@ namespace
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(TestBulletNifLoader, for_root_with_bounds_and_child_bounding_box_but_should_use_bounding_box)
|
||||||
for_root_and_child_nif_node_with_bounding_box_but_root_without_flag_should_use_child_bounds)
|
|
||||||
{
|
{
|
||||||
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
mNode.mName = "Bounding Box";
|
||||||
mNode.mBounds.mType = Nif::BoundingVolume::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);
|
||||||
|
@ -493,10 +491,10 @@ namespace
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(
|
||||||
for_root_and_two_children_where_both_with_bounds_but_only_first_with_flag_should_use_first_bounds)
|
TestBulletNifLoader, for_root_and_two_children_where_both_with_bounds_but_one_is_bounding_box_use_bounding_box)
|
||||||
{
|
{
|
||||||
mNode.mFlags |= Nif::NiAVObject::Flag_BBoxCollision;
|
mNode.mName = "Bounding Box";
|
||||||
mNode.mBounds.mType = Nif::BoundingVolume::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);
|
||||||
|
@ -530,14 +528,14 @@ 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_second_is_bounding_box_use_bounding_box)
|
||||||
{
|
{
|
||||||
mNode.mBounds.mType = Nif::BoundingVolume::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.mName = "Bounding Box";
|
||||||
mNode2.mBounds.mType = Nif::BoundingVolume::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);
|
||||||
|
@ -565,8 +563,7 @@ namespace
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(TestBulletNifLoader, for_root_nif_node_with_bounds_should_return_shape_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::BoundingVolume::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);
|
||||||
|
@ -579,8 +576,6 @@ namespace
|
||||||
const auto result = mLoader.load(file);
|
const auto result = mLoader.load(file);
|
||||||
|
|
||||||
Resource::BulletShape expected;
|
Resource::BulletShape expected;
|
||||||
expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3);
|
|
||||||
expected.mCollisionBox.mCenter = osg::Vec3f(-1, -2, -3);
|
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
@ -605,8 +600,7 @@ namespace
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestBulletNifLoader,
|
TEST_F(TestBulletNifLoader, for_tri_shape_root_node_with_bounds_should_return_static_shape)
|
||||||
for_tri_shape_root_node_with_bounds_should_return_static_shape_with_bounds_but_with_null_collision_shape)
|
|
||||||
{
|
{
|
||||||
mNiTriShape.mBounds.mType = Nif::BoundingVolume::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);
|
||||||
|
@ -618,9 +612,14 @@ namespace
|
||||||
|
|
||||||
const auto result = mLoader.load(file);
|
const auto result = mLoader.load(file);
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> triangles(new btTriangleMesh(false));
|
||||||
|
triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0));
|
||||||
|
|
||||||
|
std::unique_ptr<btCompoundShape> compound(new btCompoundShape);
|
||||||
|
compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true));
|
||||||
|
|
||||||
Resource::BulletShape expected;
|
Resource::BulletShape expected;
|
||||||
expected.mCollisionBox.mExtents = osg::Vec3f(1, 2, 3);
|
expected.mCollisionShape.reset(compound.release());
|
||||||
expected.mCollisionBox.mCenter = osg::Vec3f(-1, -2, -3);
|
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,33 +214,25 @@ namespace NifBullet
|
||||||
// Return: use bounding box for collision?
|
// Return: use bounding box for collision?
|
||||||
bool BulletNifLoader::findBoundingBox(const Nif::NiAVObject& node)
|
bool BulletNifLoader::findBoundingBox(const Nif::NiAVObject& node)
|
||||||
{
|
{
|
||||||
unsigned int type = node.mBounds.mType;
|
if (Misc::StringUtils::ciEqual(node.mName, "Bounding Box"))
|
||||||
switch (type)
|
{
|
||||||
|
if (node.mBounds.mType == Nif::BoundingVolume::Type::BOX_BV)
|
||||||
{
|
{
|
||||||
case Nif::BoundingVolume::Type::BASE_BV:
|
|
||||||
break;
|
|
||||||
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;
|
}
|
||||||
default:
|
else
|
||||||
{
|
{
|
||||||
std::stringstream warning;
|
warn("Invalid Bounding Box node bounds in file " + mShape->mFileName);
|
||||||
warning << "Unsupported BoundingVolume type " << type << " in node " << node.recIndex;
|
|
||||||
warning << " in file " << mShape->mFileName;
|
|
||||||
warn(warning.str());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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 (auto ninode = dynamic_cast<const Nif::NiNode*>(&node))
|
||||||
{
|
|
||||||
for (const auto& child : ninode->mChildren)
|
for (const auto& child : ninode->mChildren)
|
||||||
if (!child.empty() && findBoundingBox(child.get()))
|
if (!child.empty() && findBoundingBox(child.get()))
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,14 +371,8 @@ namespace NifBullet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.mAutogenerated || args.mIsCollisionNode)
|
if ((args.mAutogenerated || args.mIsCollisionNode) && isTypeNiGeometry(node.recType))
|
||||||
{
|
|
||||||
// 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.mBounds.mType == Nif::BoundingVolume::Type::BASE_BV && isTypeNiGeometry(node.recType))
|
|
||||||
handleNiTriShape(static_cast<const Nif::NiGeometry&>(node), parent, args);
|
handleNiTriShape(static_cast<const Nif::NiGeometry&>(node), parent, args);
|
||||||
}
|
|
||||||
|
|
||||||
// For NiNodes, loop through children
|
// For NiNodes, loop through children
|
||||||
if (const Nif::NiNode* ninode = dynamic_cast<const Nif::NiNode*>(&node))
|
if (const Nif::NiNode* ninode = dynamic_cast<const Nif::NiNode*>(&node))
|
||||||
|
|
Loading…
Reference in a new issue