Fix multiple-strip NiTriStrips loading

pull/2481/head
capostrophic 5 years ago
parent fa910299d0
commit 9e93c9ecd2

@ -98,12 +98,14 @@ void NiTriStripsData::read(NIFStream *nif)
/*int tris =*/ nif->getUShort();
// Number of triangle strips
int numStrips = nif->getUShort();
// Number of points in each strip
int lengths = nif->getUShort();
std::vector<unsigned short> lengths;
nif->getUShorts(lengths, numStrips);
for (int i = 0; i < numStrips; i++)
{
std::vector<unsigned short> strip;
nif->getUShorts(strip, lengths);
nif->getUShorts(strip, lengths[i]);
strips.emplace_back(strip);
}
}

@ -58,16 +58,25 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsD
{
const std::vector<osg::Vec3f> &vertices = data.vertices;
const std::vector<std::vector<unsigned short>> &strips = data.strips;
// Can't make a triangle from less than three vertices. All strips have the same size.
if (vertices.empty() || strips.empty() || strips[0].size() < 3)
if (vertices.empty() || strips.empty())
return;
mesh.preallocateVertices(static_cast<int>(data.vertices.size()));
// There are N+2*M vertex indices overall, so we must substract 2*M (N triangles, M strips)
mesh.preallocateIndices(static_cast<int>((strips.size()-2) * strips[0].size()));
int numTriangles = 0;
for (const std::vector<unsigned short>& strip : strips)
{
// Each strip with N points contains information about N-2 triangles.
if (strip.size() >= 3)
numTriangles += static_cast<int>(strip.size()-2);
}
mesh.preallocateIndices(static_cast<int>(numTriangles));
// It's triangulation time. Totally not a NifSkope spell ripoff.
for (const std::vector<unsigned short>& strip : strips)
{
// Can't make a triangle from less than 3 points.
if (strip.size() < 3)
continue;
unsigned short a = strip[0], b = strip[0], c = strip[1];
for (int i = 2; i < static_cast<int>(strip.size()); i++)
{

@ -1081,11 +1081,17 @@ namespace NifOsg
const Nif::NiTriStripsData* data = triStrips->data.getPtr();
vertexColorsPresent = !data->colors.empty();
triCommonToGeometry(geometry, data->vertices, data->normals, data->uvlist, data->colors, boundTextures, triStrips->name);
// Can't make a triangle from less than three vertices. All strips have the same size.
if (!data->strips.empty() && data->strips[0].size() >= 3)
if (!data->strips.empty())
{
for (const std::vector<unsigned short>& strip : data->strips)
{
// Can't make a triangle from less than three vertices.
if (strip.size() < 3)
continue;
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(),
(unsigned short*)strip.data()));
}
}
}
// osg::Material properties are handled here for two reasons:

Loading…
Cancel
Save