mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-14 01:19:59 +00:00
Refactor NiGeometry/BSTriShape
Don't pass invalid geometry data links to the loaders
This commit is contained in:
parent
deb051639e
commit
bff9231c3b
@ -33,8 +33,8 @@ namespace Nif::Testing
|
||||
inline void init(NiGeometry& value)
|
||||
{
|
||||
init(static_cast<NiAVObject&>(value));
|
||||
value.data = NiGeometryDataPtr(nullptr);
|
||||
value.skin = NiSkinInstancePtr(nullptr);
|
||||
value.mData = NiGeometryDataPtr(nullptr);
|
||||
value.mSkin = NiSkinInstancePtr(nullptr);
|
||||
}
|
||||
|
||||
inline void init(NiTriShape& value)
|
||||
|
@ -326,20 +326,20 @@ namespace
|
||||
mNiTriShapeData.mVertices = { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0) };
|
||||
mNiTriShapeData.mNumTriangles = 1;
|
||||
mNiTriShapeData.mTriangles = { 0, 1, 2 };
|
||||
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
mNiTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
|
||||
mNiTriShapeData2.recType = Nif::RC_NiTriShapeData;
|
||||
mNiTriShapeData2.mVertices = { osg::Vec3f(0, 0, 1), osg::Vec3f(1, 0, 1), osg::Vec3f(1, 1, 1) };
|
||||
mNiTriShapeData2.mNumTriangles = 1;
|
||||
mNiTriShapeData2.mTriangles = { 0, 1, 2 };
|
||||
mNiTriShape2.data = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
||||
mNiTriShape2.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData2);
|
||||
|
||||
mNiTriStripsData.recType = Nif::RC_NiTriStripsData;
|
||||
mNiTriStripsData.mVertices
|
||||
= { osg::Vec3f(0, 0, 0), osg::Vec3f(1, 0, 0), osg::Vec3f(1, 1, 0), osg::Vec3f(0, 1, 0) };
|
||||
mNiTriStripsData.mNumTriangles = 2;
|
||||
mNiTriStripsData.mStrips = { { 0, 1, 2, 3 } };
|
||||
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||
mNiTriStrips.mData = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||
}
|
||||
};
|
||||
|
||||
@ -703,7 +703,7 @@ namespace
|
||||
TEST_F(TestBulletNifLoader,
|
||||
for_tri_shape_child_node_and_filename_starting_with_x_and_not_empty_skin_should_return_static_shape)
|
||||
{
|
||||
mNiTriShape.skin = Nif::NiSkinInstancePtr(&mNiSkinInstance);
|
||||
mNiTriShape.mSkin = Nif::NiSkinInstancePtr(&mNiSkinInstance);
|
||||
mNiTriShape.mParents.push_back(&mNiNode);
|
||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
||||
|
||||
@ -943,7 +943,7 @@ 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.mData = Nif::NiGeometryDataPtr(nullptr);
|
||||
mNiTriShape.mParents.push_back(&mNiNode);
|
||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
||||
|
||||
@ -961,7 +961,7 @@ namespace
|
||||
TEST_F(TestBulletNifLoader,
|
||||
for_tri_shape_child_node_with_empty_data_triangles_should_return_shape_with_null_collision_shape)
|
||||
{
|
||||
auto data = static_cast<Nif::NiTriShapeData*>(mNiTriShape.data.getPtr());
|
||||
auto data = static_cast<Nif::NiTriShapeData*>(mNiTriShape.mData.getPtr());
|
||||
data->mTriangles.clear();
|
||||
mNiTriShape.mParents.push_back(&mNiNode);
|
||||
mNiNode.mChildren = Nif::NiAVObjectList{ Nif::NiAVObjectPtr(&mNiTriShape) };
|
||||
@ -1095,7 +1095,7 @@ namespace
|
||||
init(niTriShape);
|
||||
init(emptyCollisionNode);
|
||||
|
||||
niTriShape.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
niTriShape.mData = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
niTriShape.mParents.push_back(&mNiNode);
|
||||
|
||||
emptyCollisionNode.recType = Nif::RC_RootCollisionNode;
|
||||
@ -1192,21 +1192,6 @@ namespace
|
||||
EXPECT_EQ(*result, expected);
|
||||
}
|
||||
|
||||
TEST_F(TestBulletNifLoader, should_ignore_tri_shape_data_with_mismatching_data_rec_type)
|
||||
{
|
||||
mNiTriShape.data = Nif::NiGeometryDataPtr(&mNiTriStripsData);
|
||||
|
||||
Nif::NIFFile file("test.nif");
|
||||
file.mRoots.push_back(&mNiTriShape);
|
||||
file.mHash = mHash;
|
||||
|
||||
const auto result = mLoader.load(file);
|
||||
|
||||
const Resource::BulletShape expected;
|
||||
|
||||
EXPECT_EQ(*result, expected);
|
||||
}
|
||||
|
||||
TEST_F(TestBulletNifLoader, for_tri_strips_root_node_should_return_static_shape)
|
||||
{
|
||||
Nif::NIFFile file("test.nif");
|
||||
@ -1227,21 +1212,6 @@ namespace
|
||||
EXPECT_EQ(*result, expected);
|
||||
}
|
||||
|
||||
TEST_F(TestBulletNifLoader, should_ignore_tri_strips_data_with_mismatching_data_rec_type)
|
||||
{
|
||||
mNiTriStrips.data = Nif::NiGeometryDataPtr(&mNiTriShapeData);
|
||||
|
||||
Nif::NIFFile file("test.nif");
|
||||
file.mRoots.push_back(&mNiTriStrips);
|
||||
file.mHash = mHash;
|
||||
|
||||
const auto result = mLoader.load(file);
|
||||
|
||||
const Resource::BulletShape expected;
|
||||
|
||||
EXPECT_EQ(*result, expected);
|
||||
}
|
||||
|
||||
TEST_F(TestBulletNifLoader, should_ignore_tri_strips_data_with_empty_strips)
|
||||
{
|
||||
mNiTriStripsData.mStrips.clear();
|
||||
|
@ -167,14 +167,14 @@ namespace Nif
|
||||
{
|
||||
NiAVObject::read(nif);
|
||||
|
||||
data.read(nif);
|
||||
skin.read(nif);
|
||||
mData.read(nif);
|
||||
mSkin.read(nif);
|
||||
mMaterial.read(nif);
|
||||
if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS
|
||||
&& nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
||||
{
|
||||
shaderprop.read(nif);
|
||||
alphaprop.read(nif);
|
||||
mShaderProperty.read(nif);
|
||||
mAlphaProperty.read(nif);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,12 +182,38 @@ namespace Nif
|
||||
{
|
||||
NiAVObject::post(nif);
|
||||
|
||||
data.post(nif);
|
||||
skin.post(nif);
|
||||
shaderprop.post(nif);
|
||||
alphaprop.post(nif);
|
||||
if (recType != RC_NiParticles && !skin.empty())
|
||||
mData.post(nif);
|
||||
mSkin.post(nif);
|
||||
mShaderProperty.post(nif);
|
||||
mAlphaProperty.post(nif);
|
||||
if (recType != RC_NiParticles && !mSkin.empty())
|
||||
nif.setUseSkinning(true);
|
||||
|
||||
if (!mData.empty())
|
||||
{
|
||||
switch (recType)
|
||||
{
|
||||
case RC_NiTriShape:
|
||||
case RC_BSLODTriShape:
|
||||
if (mData->recType != RC_NiTriShapeData)
|
||||
mData = NiGeometryDataPtr(nullptr);
|
||||
break;
|
||||
case RC_NiTriStrips:
|
||||
if (mData->recType != RC_NiTriStripsData)
|
||||
mData = NiGeometryDataPtr(nullptr);
|
||||
break;
|
||||
case RC_NiParticles:
|
||||
if (mData->recType != RC_NiParticlesData)
|
||||
mData = NiGeometryDataPtr(nullptr);
|
||||
break;
|
||||
case RC_NiLines:
|
||||
if (mData->recType != RC_NiLinesData)
|
||||
mData = NiGeometryDataPtr(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BSLODTriShape::read(NIFStream* nif)
|
||||
|
@ -119,7 +119,14 @@ namespace Nif
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
struct NiGeometry : NiAVObject
|
||||
struct GeometryInterface
|
||||
{
|
||||
NiSkinInstancePtr mSkin;
|
||||
BSShaderPropertyPtr mShaderProperty;
|
||||
NiAlphaPropertyPtr mAlphaProperty;
|
||||
};
|
||||
|
||||
struct NiGeometry : NiAVObject, GeometryInterface
|
||||
{
|
||||
/* Possible flags:
|
||||
0x40 - mesh has no vertex normals ?
|
||||
@ -138,17 +145,13 @@ namespace Nif
|
||||
void read(NIFStream* nif);
|
||||
};
|
||||
|
||||
NiGeometryDataPtr data;
|
||||
NiSkinInstancePtr skin;
|
||||
NiGeometryDataPtr mData;
|
||||
MaterialData mMaterial;
|
||||
BSShaderPropertyPtr shaderprop;
|
||||
NiAlphaPropertyPtr alphaprop;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
};
|
||||
|
||||
// TODO: consider checking the data record type here
|
||||
struct NiTriShape : NiGeometry
|
||||
{
|
||||
};
|
||||
@ -337,13 +340,10 @@ namespace Nif
|
||||
void read(NIFStream* nif, uint16_t flags);
|
||||
};
|
||||
|
||||
struct BSTriShape : NiAVObject
|
||||
struct BSTriShape : NiAVObject, GeometryInterface
|
||||
{
|
||||
osg::BoundingSpheref mBoundingSphere;
|
||||
std::array<float, 6> mBoundMinMax;
|
||||
NiSkinInstancePtr mSkin;
|
||||
BSShaderPropertyPtr mShaderProperty;
|
||||
NiAlphaPropertyPtr mAlphaProperty;
|
||||
BSVertexDesc mVertDesc;
|
||||
uint32_t mDataSize;
|
||||
std::vector<BSVertexData> mVertData;
|
||||
|
@ -79,14 +79,11 @@ namespace
|
||||
|
||||
template <class Function>
|
||||
auto handleNiGeometry(const Nif::NiGeometry& geometry, Function&& function)
|
||||
-> decltype(function(static_cast<const Nif::NiTriShapeData&>(geometry.data.get())))
|
||||
-> decltype(function(static_cast<const Nif::NiTriShapeData&>(geometry.mData.get())))
|
||||
{
|
||||
if (geometry.recType == Nif::RC_NiTriShape || geometry.recType == Nif::RC_BSLODTriShape)
|
||||
{
|
||||
if (geometry.data->recType != Nif::RC_NiTriShapeData)
|
||||
return {};
|
||||
|
||||
auto data = static_cast<const Nif::NiTriShapeData*>(geometry.data.getPtr());
|
||||
auto data = static_cast<const Nif::NiTriShapeData*>(geometry.mData.getPtr());
|
||||
if (data->mTriangles.empty())
|
||||
return {};
|
||||
|
||||
@ -95,10 +92,7 @@ namespace
|
||||
|
||||
if (geometry.recType == Nif::RC_NiTriStrips)
|
||||
{
|
||||
if (geometry.data->recType != Nif::RC_NiTriStripsData)
|
||||
return {};
|
||||
|
||||
auto data = static_cast<const Nif::NiTriStripsData*>(geometry.data.getPtr());
|
||||
auto data = static_cast<const Nif::NiTriStripsData*>(geometry.mData.getPtr());
|
||||
if (data->mStrips.empty())
|
||||
return {};
|
||||
|
||||
@ -366,10 +360,10 @@ namespace NifBullet
|
||||
if (args.mHasMarkers && Misc::StringUtils::ciStartsWith(niGeometry.mName, "EditorMarker"))
|
||||
return;
|
||||
|
||||
if (niGeometry.data.empty() || niGeometry.data->mVertices.empty())
|
||||
if (niGeometry.mData.empty() || niGeometry.mData->mVertices.empty())
|
||||
return;
|
||||
|
||||
if (!niGeometry.skin.empty())
|
||||
if (!niGeometry.mSkin.empty())
|
||||
args.mAnimated = false;
|
||||
// TODO: handle NiSkinPartition
|
||||
|
||||
|
@ -128,10 +128,10 @@ namespace
|
||||
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
||||
if (geometry)
|
||||
{
|
||||
if (!geometry->shaderprop.empty())
|
||||
out.emplace_back(geometry->shaderprop.getPtr());
|
||||
if (!geometry->alphaprop.empty())
|
||||
out.emplace_back(geometry->alphaprop.getPtr());
|
||||
if (!geometry->mShaderProperty.empty())
|
||||
out.emplace_back(geometry->mShaderProperty.getPtr());
|
||||
if (!geometry->mAlphaProperty.empty())
|
||||
out.emplace_back(geometry->mAlphaProperty.getPtr());
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,8 +444,8 @@ namespace NifOsg
|
||||
|
||||
auto geometry = dynamic_cast<const Nif::NiGeometry*>(nifNode);
|
||||
// NiGeometry's NiAlphaProperty doesn't get handled here because it's a drawable property
|
||||
if (geometry && !geometry->shaderprop.empty())
|
||||
handleProperty(geometry->shaderprop.getPtr(), applyTo, composite, imageManager, boundTextures,
|
||||
if (geometry && !geometry->mShaderProperty.empty())
|
||||
handleProperty(geometry->mShaderProperty.getPtr(), applyTo, composite, imageManager, boundTextures,
|
||||
animflags, hasStencilProperty);
|
||||
}
|
||||
|
||||
@ -761,7 +761,7 @@ namespace NifOsg
|
||||
skip = args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->mName, "EditorMarker");
|
||||
if (!skip)
|
||||
{
|
||||
Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->skin;
|
||||
Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->mSkin;
|
||||
|
||||
if (skin.empty())
|
||||
handleGeometry(nifNode, parent, node, composite, args.mBoundTextures, args.mAnimFlags);
|
||||
@ -1121,13 +1121,13 @@ namespace NifOsg
|
||||
const Nif::NiAVObject* nifNode, ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl)
|
||||
{
|
||||
auto particleNode = static_cast<const Nif::NiParticles*>(nifNode);
|
||||
if (particleNode->data.empty() || particleNode->data->recType != Nif::RC_NiParticlesData)
|
||||
if (particleNode->mData.empty())
|
||||
{
|
||||
partsys->setQuota(partctrl->mParticles.size());
|
||||
return;
|
||||
}
|
||||
|
||||
auto particledata = static_cast<const Nif::NiParticlesData*>(particleNode->data.getPtr());
|
||||
auto particledata = static_cast<const Nif::NiParticlesData*>(particleNode->mData.getPtr());
|
||||
partsys->setQuota(particledata->mNumParticles);
|
||||
|
||||
osg::BoundingBox box;
|
||||
@ -1379,13 +1379,13 @@ namespace NifOsg
|
||||
const std::vector<unsigned int>& boundTextures, int animflags)
|
||||
{
|
||||
const Nif::NiGeometry* niGeometry = static_cast<const Nif::NiGeometry*>(nifNode);
|
||||
if (niGeometry->data.empty())
|
||||
if (niGeometry->mData.empty())
|
||||
return;
|
||||
|
||||
bool hasPartitions = false;
|
||||
if (!niGeometry->skin.empty())
|
||||
if (!niGeometry->mSkin.empty())
|
||||
{
|
||||
const Nif::NiSkinInstance* skin = niGeometry->skin.getPtr();
|
||||
const Nif::NiSkinInstance* skin = niGeometry->mSkin.getPtr();
|
||||
const Nif::NiSkinData* data = nullptr;
|
||||
const Nif::NiSkinPartition* partitions = nullptr;
|
||||
if (!skin->mData.empty())
|
||||
@ -1419,13 +1419,11 @@ namespace NifOsg
|
||||
}
|
||||
}
|
||||
|
||||
const Nif::NiGeometryData* niGeometryData = niGeometry->data.getPtr();
|
||||
const Nif::NiGeometryData* niGeometryData = niGeometry->mData.getPtr();
|
||||
if (!hasPartitions)
|
||||
{
|
||||
if (niGeometry->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_BSLODTriShape)
|
||||
{
|
||||
if (niGeometryData->recType != Nif::RC_NiTriShapeData)
|
||||
return;
|
||||
auto data = static_cast<const Nif::NiTriShapeData*>(niGeometryData);
|
||||
const std::vector<unsigned short>& triangles = data->mTriangles;
|
||||
if (triangles.empty())
|
||||
@ -1435,8 +1433,6 @@ namespace NifOsg
|
||||
}
|
||||
else if (niGeometry->recType == Nif::RC_NiTriStrips)
|
||||
{
|
||||
if (niGeometryData->recType != Nif::RC_NiTriStripsData)
|
||||
return;
|
||||
auto data = static_cast<const Nif::NiTriStripsData*>(niGeometryData);
|
||||
bool hasGeometry = false;
|
||||
for (const std::vector<unsigned short>& strip : data->mStrips)
|
||||
@ -1452,8 +1448,6 @@ namespace NifOsg
|
||||
}
|
||||
else if (niGeometry->recType == Nif::RC_NiLines)
|
||||
{
|
||||
if (niGeometryData->recType != Nif::RC_NiLinesData)
|
||||
return;
|
||||
auto data = static_cast<const Nif::NiLinesData*>(niGeometryData);
|
||||
const auto& line = data->mLines;
|
||||
if (line.empty())
|
||||
@ -1545,7 +1539,7 @@ namespace NifOsg
|
||||
// Assign bone weights
|
||||
osg::ref_ptr<SceneUtil::RigGeometry::InfluenceMap> map(new SceneUtil::RigGeometry::InfluenceMap);
|
||||
|
||||
const Nif::NiSkinInstance* skin = static_cast<const Nif::NiGeometry*>(nifNode)->skin.getPtr();
|
||||
const Nif::NiSkinInstance* skin = static_cast<const Nif::NiGeometry*>(nifNode)->mSkin.getPtr();
|
||||
const Nif::NiSkinData* data = skin->mData.getPtr();
|
||||
const Nif::NiAVObjectList& bones = skin->mBones;
|
||||
for (std::size_t i = 0; i < bones.size(); ++i)
|
||||
|
Loading…
x
Reference in New Issue
Block a user