mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-19 03:39:58 +00:00
Avoid mesh allocation when data is invalid
This commit is contained in:
parent
4ac83f4c39
commit
4e8e8304aa
@ -1159,8 +1159,7 @@ namespace
|
|||||||
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif"));
|
EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("xtest.nif"));
|
||||||
const auto result = mLoader.load(mNifFile);
|
const auto result = mLoader.load(mNifFile);
|
||||||
|
|
||||||
Resource::BulletShape expected;
|
const Resource::BulletShape expected;
|
||||||
expected.mCollisionShape.reset(new btCompoundShape);
|
|
||||||
|
|
||||||
EXPECT_EQ(*result, expected);
|
EXPECT_EQ(*result, expected);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "bulletnifloader.hpp"
|
#include "bulletnifloader.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
#include <BulletCollision/CollisionShapes/btTriangleMesh.h>
|
#include <BulletCollision/CollisionShapes/btTriangleMesh.h>
|
||||||
@ -99,12 +100,38 @@ void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiGeometry& geometry, const osg::Matrixf &transform = osg::Matrixf())
|
template <class Function>
|
||||||
|
auto handleNiGeometry(const Nif::NiGeometry& geometry, Function&& function)
|
||||||
|
-> decltype(function(static_cast<const Nif::NiTriShapeData&>(geometry.data.get())))
|
||||||
{
|
{
|
||||||
if (geometry.recType == Nif::RC_NiTriShape || geometry.recType == Nif::RC_BSLODTriShape)
|
if (geometry.recType == Nif::RC_NiTriShape || geometry.recType == Nif::RC_BSLODTriShape)
|
||||||
fillTriangleMesh(mesh, static_cast<const Nif::NiTriShapeData&>(geometry.data.get()), transform);
|
return function(static_cast<const Nif::NiTriShapeData&>(geometry.data.get()));
|
||||||
else if (geometry.recType == Nif::RC_NiTriStrips)
|
|
||||||
fillTriangleMesh(mesh, static_cast<const Nif::NiTriStripsData&>(geometry.data.get()), transform);
|
if (geometry.recType == Nif::RC_NiTriStrips)
|
||||||
|
return function(static_cast<const Nif::NiTriStripsData&>(geometry.data.get()));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::monostate fillTriangleMesh(std::unique_ptr<btTriangleMesh>& mesh, const Nif::NiGeometry& geometry, const osg::Matrixf &transform)
|
||||||
|
{
|
||||||
|
return handleNiGeometry(geometry, [&] (const auto& data)
|
||||||
|
{
|
||||||
|
if (mesh == nullptr)
|
||||||
|
mesh.reset(new btTriangleMesh(false));
|
||||||
|
fillTriangleMesh(*mesh, data, transform);
|
||||||
|
return std::monostate {};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<btTriangleMesh> makeChildMesh(const Nif::NiGeometry& geometry)
|
||||||
|
{
|
||||||
|
return handleNiGeometry(geometry, [&] (const auto& data)
|
||||||
|
{
|
||||||
|
std::unique_ptr<btTriangleMesh> mesh(new btTriangleMesh);
|
||||||
|
fillTriangleMesh(*mesh, data, osg::Matrixf());
|
||||||
|
return mesh;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -369,16 +396,13 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiGeometry& niGeometry, const
|
|||||||
|
|
||||||
if (isAnimated)
|
if (isAnimated)
|
||||||
{
|
{
|
||||||
|
std::unique_ptr<btTriangleMesh> childMesh = makeChildMesh(niGeometry);
|
||||||
|
if (childMesh == nullptr || childMesh->getNumTriangles() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!mCompoundShape)
|
if (!mCompoundShape)
|
||||||
mCompoundShape.reset(new btCompoundShape);
|
mCompoundShape.reset(new btCompoundShape);
|
||||||
|
|
||||||
std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh);
|
|
||||||
|
|
||||||
fillTriangleMesh(*childMesh, niGeometry);
|
|
||||||
|
|
||||||
if (childMesh->getNumTriangles() == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true));
|
std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true));
|
||||||
childMesh.release();
|
childMesh.release();
|
||||||
|
|
||||||
@ -397,20 +421,9 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiGeometry& niGeometry, const
|
|||||||
childShape.release();
|
childShape.release();
|
||||||
}
|
}
|
||||||
else if (avoid)
|
else if (avoid)
|
||||||
{
|
fillTriangleMesh(mAvoidStaticMesh, niGeometry, transform);
|
||||||
if (!mAvoidStaticMesh)
|
|
||||||
mAvoidStaticMesh.reset(new btTriangleMesh(false));
|
|
||||||
|
|
||||||
fillTriangleMesh(*mAvoidStaticMesh, niGeometry, transform);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
fillTriangleMesh(mStaticMesh, niGeometry, transform);
|
||||||
if (!mStaticMesh)
|
|
||||||
mStaticMesh.reset(new btTriangleMesh(false));
|
|
||||||
|
|
||||||
// Static shape, just transform all vertices into position
|
|
||||||
fillTriangleMesh(*mStaticMesh, niGeometry, transform);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace NifBullet
|
} // namespace NifBullet
|
||||||
|
Loading…
x
Reference in New Issue
Block a user