From 754c5a8e2a3bcd5b66e1a48350ddcd558fabaf94 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Mon, 4 Dec 2023 23:43:35 +0300 Subject: [PATCH] Restore animated collision shape rescaling --- apps/openmw/mwphysics/object.cpp | 12 +- .../nifloader/testbulletnifloader.cpp | 126 +++++++++++++----- components/nifbullet/bulletnifloader.cpp | 15 ++- components/resource/bulletshape.cpp | 6 +- components/resource/bulletshape.hpp | 19 ++- 5 files changed, 132 insertions(+), 46 deletions(-) diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index 6e0e2cdc7f..53529ec729 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -137,6 +137,7 @@ namespace MWPhysics osg::NodePath& nodePath = nodePathFound->second; osg::Matrixf matrix = osg::computeLocalToWorld(nodePath); + btVector3 scale = Misc::Convert::toBullet(matrix.getScale()); matrix.orthoNormalize(matrix); btTransform transform; @@ -145,8 +146,15 @@ namespace MWPhysics for (int j = 0; j < 3; ++j) transform.getBasis()[i][j] = matrix(j, i); // NB column/row major difference - // Note: we can not apply scaling here for now since we treat scaled shapes - // as new shapes (btScaledBvhTriangleMeshShape) with 1.0 scale for now + btCollisionShape* childShape = compound->getChildShape(shapeIndex); + btVector3 newScale = compound->getLocalScaling() * scale; + + if (childShape->getLocalScaling() != newScale) + { + childShape->setLocalScaling(newScale); + result = true; + } + if (!(transform == compound->getChildTransform(shapeIndex))) { compound->updateChildTransform(shapeIndex, transform); diff --git a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp index 7dce21bac6..d44561a68b 100644 --- a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp +++ b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp @@ -144,6 +144,12 @@ namespace Resource return stream << "}}"; } + static std::ostream& operator<<(std::ostream& stream, const ScaledTriangleMeshShape& value) + { + return stream << "Resource::ScaledTriangleMeshShape {" << value.getLocalScaling() << ", " + << value.getChildShape() << "}"; + } + static bool operator==(const CollisionBox& l, const CollisionBox& r) { const auto tie = [](const CollisionBox& v) { return std::tie(v.mExtents, v.mCenter); }; @@ -169,6 +175,10 @@ static std::ostream& operator<<(std::ostream& stream, const btCollisionShape& va if (const auto casted = dynamic_cast(&value)) return stream << *casted; break; + case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + if (const auto casted = dynamic_cast(&value)) + return stream << *casted; + break; } return stream << "btCollisionShape {" << value.getShapeType() << "}"; } @@ -249,6 +259,12 @@ static bool operator==(const btBvhTriangleMeshShape& lhs, const btBvhTriangleMes && lhs.getOwnsBvh() == rhs.getOwnsBvh() && isNear(getTriangles(lhs), getTriangles(rhs)); } +static bool operator==(const btScaledBvhTriangleMeshShape& lhs, const btScaledBvhTriangleMeshShape& rhs) +{ + return isNear(lhs.getLocalScaling(), rhs.getLocalScaling()) + && compareObjects(lhs.getChildShape(), rhs.getChildShape()); +} + static bool operator==(const btCollisionShape& lhs, const btCollisionShape& rhs) { if (lhs.getShapeType() != rhs.getShapeType()) @@ -264,6 +280,11 @@ static bool operator==(const btCollisionShape& lhs, const btCollisionShape& rhs) if (const auto rhsCasted = dynamic_cast(&rhs)) return *lhsCasted == *rhsCasted; return false; + case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + if (const auto lhsCasted = dynamic_cast(&lhs)) + if (const auto rhsCasted = dynamic_cast(&rhs)) + return *lhsCasted == *rhsCasted; + return false; } return false; } @@ -572,7 +593,9 @@ namespace triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + auto triShape = std::make_unique(triangles.release(), true); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(triShape.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -596,7 +619,9 @@ namespace triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + auto triShape = std::make_unique(triangles.release(), true); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(triShape.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -619,7 +644,9 @@ namespace triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + auto triShape = std::make_unique(triangles.release(), true); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(triShape.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -644,7 +671,9 @@ namespace triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + auto triShape = std::make_unique(triangles.release(), true); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(triShape.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -669,9 +698,13 @@ namespace std::unique_ptr triangles2(new btTriangleMesh(false)); triangles2->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + auto triShape = std::make_unique(triangles.release(), true); + auto triShape2 = std::make_unique(triangles2.release(), true); + compound->addChildShape( - btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles2.release(), true)); + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(triShape.release(), btVector3(1, 1, 1))); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(triShape2.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -695,7 +728,9 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + auto triShape = std::make_unique(triangles.release(), true); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(triShape.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -717,9 +752,8 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); - mesh->setLocalScaling(btVector3(3, 3, 3)); std::unique_ptr shape(new btCompoundShape); - shape->addChildShape(mTransform, mesh.release()); + shape->addChildShape(mTransform, new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(3, 3, 3))); Resource::BulletShape expected; expected.mCollisionShape.reset(shape.release()); expected.mAnimatedShapes = { { -1, 0 } }; @@ -744,9 +778,9 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); - mesh->setLocalScaling(btVector3(12, 12, 12)); std::unique_ptr shape(new btCompoundShape); - shape->addChildShape(mTransformScale4, mesh.release()); + shape->addChildShape( + mTransformScale4, new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(12, 12, 12))); Resource::BulletShape expected; expected.mCollisionShape.reset(shape.release()); expected.mAnimatedShapes = { { -1, 0 } }; @@ -776,16 +810,14 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); - mesh->setLocalScaling(btVector3(3, 3, 3)); std::unique_ptr triangles2(new btTriangleMesh(false)); triangles2->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1)); std::unique_ptr mesh2(new Resource::TriangleMeshShape(triangles2.release(), true)); - mesh2->setLocalScaling(btVector3(3, 3, 3)); std::unique_ptr shape(new btCompoundShape); - shape->addChildShape(mTransform, mesh.release()); - shape->addChildShape(mTransform, mesh2.release()); + shape->addChildShape(mTransform, new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(3, 3, 3))); + shape->addChildShape(mTransform, new Resource::ScaledTriangleMeshShape(mesh2.release(), btVector3(3, 3, 3))); Resource::BulletShape expected; expected.mCollisionShape.reset(shape.release()); expected.mAnimatedShapes = { { -1, 0 } }; @@ -813,9 +845,9 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); - mesh->setLocalScaling(btVector3(12, 12, 12)); std::unique_ptr shape(new btCompoundShape); - shape->addChildShape(mTransformScale4, mesh.release()); + shape->addChildShape( + mTransformScale4, new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(12, 12, 12))); Resource::BulletShape expected; expected.mCollisionShape.reset(shape.release()); expected.mAnimatedShapes = { { -1, 0 } }; @@ -849,16 +881,16 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); - mesh->setLocalScaling(btVector3(12, 12, 12)); std::unique_ptr triangles2(new btTriangleMesh(false)); triangles2->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1)); std::unique_ptr mesh2(new Resource::TriangleMeshShape(triangles2.release(), true)); - mesh2->setLocalScaling(btVector3(12, 12, 12)); std::unique_ptr shape(new btCompoundShape); - shape->addChildShape(mTransformScale4, mesh.release()); - shape->addChildShape(mTransformScale4, mesh2.release()); + shape->addChildShape( + mTransformScale4, new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(12, 12, 12))); + shape->addChildShape( + mTransformScale4, new Resource::ScaledTriangleMeshShape(mesh2.release(), btVector3(12, 12, 12))); Resource::BulletShape expected; expected.mCollisionShape.reset(shape.release()); expected.mAnimatedShapes = { { -1, 1 } }; @@ -880,14 +912,17 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr triangles2(new btTriangleMesh(false)); triangles2->addTriangle(btVector3(0, 0, 1), btVector3(1, 0, 1), btVector3(1, 1, 1)); + std::unique_ptr mesh2(new Resource::TriangleMeshShape(triangles2.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); compound->addChildShape( - btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles2.release(), true)); + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh2.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -911,9 +946,11 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mAvoidCollisionShape.reset(compound.release()); @@ -973,8 +1010,10 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -1002,8 +1041,10 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -1029,8 +1070,10 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -1057,8 +1100,10 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -1083,8 +1128,10 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -1116,8 +1163,10 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -1178,8 +1227,10 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); triangles->addTriangle(btVector3(1, 0, 0), btVector3(0, 1, 0), btVector3(1, 1, 0)); + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -1267,9 +1318,10 @@ namespace std::unique_ptr triangles(new btTriangleMesh(false)); triangles->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); - + std::unique_ptr mesh(new Resource::TriangleMeshShape(triangles.release(), true)); std::unique_ptr compound(new btCompoundShape); - compound->addChildShape(btTransform::getIdentity(), new Resource::TriangleMeshShape(triangles.release(), true)); + compound->addChildShape( + btTransform::getIdentity(), new Resource::ScaledTriangleMeshShape(mesh.release(), btVector3(1, 1, 1))); Resource::BulletShape expected; expected.mCollisionShape.reset(compound.release()); @@ -1298,14 +1350,14 @@ namespace std::unique_ptr triangles1(new btTriangleMesh(false)); triangles1->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr mesh1(new Resource::TriangleMeshShape(triangles1.release(), true)); - mesh1->setLocalScaling(btVector3(8, 8, 8)); std::unique_ptr triangles2(new btTriangleMesh(false)); triangles2->addTriangle(btVector3(0, 0, 0), btVector3(1, 0, 0), btVector3(1, 1, 0)); std::unique_ptr mesh2(new Resource::TriangleMeshShape(triangles2.release(), true)); - mesh2->setLocalScaling(btVector3(12, 12, 12)); std::unique_ptr shape(new btCompoundShape); - shape->addChildShape(mTransformScale2, mesh1.release()); - shape->addChildShape(mTransformScale3, mesh2.release()); + shape->addChildShape( + mTransformScale2, new Resource::ScaledTriangleMeshShape(mesh1.release(), btVector3(8, 8, 8))); + shape->addChildShape( + mTransformScale3, new Resource::ScaledTriangleMeshShape(mesh2.release(), btVector3(12, 12, 12))); Resource::BulletShape expected; expected.mCollisionShape.reset(shape.release()); expected.mAnimatedShapes = { { -1, 0 } }; diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 96dff80004..c2cd915a8c 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -281,7 +281,20 @@ namespace NifBullet osg::Matrixf transform = niGeometry.mTransform.toMatrix(); for (const Nif::Parent* parent = nodeParent; parent != nullptr; parent = parent->mParent) transform *= parent->mNiNode.mTransform.toMatrix(); - childShape->setLocalScaling(Misc::Convert::toBullet(transform.getScale())); + + if (childShape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + auto scaledShape = std::make_unique( + static_cast(childShape.get()), Misc::Convert::toBullet(transform.getScale())); + std::ignore = childShape.release(); + + childShape = std::move(scaledShape); + } + else + { + childShape->setLocalScaling(Misc::Convert::toBullet(transform.getScale())); + } + transform.orthoNormalize(transform); btTransform trans; diff --git a/components/resource/bulletshape.cpp b/components/resource/bulletshape.cpp index cc0a63359b..360b92ffc0 100644 --- a/components/resource/bulletshape.cpp +++ b/components/resource/bulletshape.cpp @@ -32,11 +32,11 @@ namespace Resource return newShape; } - if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + if (shape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) { - const btBvhTriangleMeshShape* trishape = static_cast(shape); + const btScaledBvhTriangleMeshShape* trishape = static_cast(shape); return CollisionShapePtr(new btScaledBvhTriangleMeshShape( - const_cast(trishape), btVector3(1.f, 1.f, 1.f))); + const_cast(trishape->getChildShape()), trishape->getLocalScaling())); } if (shape->getShapeType() == BOX_SHAPE_PROXYTYPE) diff --git a/components/resource/bulletshape.hpp b/components/resource/bulletshape.hpp index 9610fde49f..0a1b98bf7c 100644 --- a/components/resource/bulletshape.hpp +++ b/components/resource/bulletshape.hpp @@ -10,6 +10,7 @@ #include #include +#include class btCollisionShape; @@ -49,8 +50,8 @@ namespace Resource // collision box for creatures. For now, use one file <-> one resource for simplicity. CollisionBox mCollisionBox; - // Stores animated collision shapes. If any collision nodes in the NIF are animated, then mCollisionShape - // will be a btCompoundShape (which consists of one or more child shapes). + // Stores animated collision shapes. + // mCollisionShape is a btCompoundShape (which consists of one or more child shapes). // In this map, for each animated collision shape, // we store the node's record index mapped to the child index of the shape in the btCompoundShape. std::map mAnimatedShapes; @@ -61,6 +62,7 @@ namespace Resource VisualCollisionType mVisualCollisionType = VisualCollisionType::None; BulletShape() = default; + // Note this is always a shallow copy and the copy will not autodelete underlying vertex data BulletShape(const BulletShape& other, const osg::CopyOp& copyOp = osg::CopyOp()); META_Object(Resource, BulletShape) @@ -70,7 +72,7 @@ namespace Resource bool isAnimated() const { return !mAnimatedShapes.empty(); } }; - // An instance of a BulletShape that may have its own unique scaling set on the mCollisionShape. + // An instance of a BulletShape that may have its own unique scaling set on collision shapes. // Vertex data is shallow-copied where possible. A ref_ptr to the original shape is held to keep vertex pointers // intact. class BulletShapeInstance : public BulletShape @@ -102,6 +104,17 @@ namespace Resource } }; + // btScaledBvhTriangleMeshShape that auto-deletes the child shape + struct ScaledTriangleMeshShape : public btScaledBvhTriangleMeshShape + { + ScaledTriangleMeshShape(btBvhTriangleMeshShape* childShape, const btVector3& localScaling) + : btScaledBvhTriangleMeshShape(childShape, localScaling) + { + } + + ~ScaledTriangleMeshShape() override { delete getChildShape(); } + }; + } #endif