diff --git a/components/nif/data.cpp b/components/nif/data.cpp index 3ed7d5c3c..4a9266239 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -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 lengths; + nif->getUShorts(lengths, numStrips); + for (int i = 0; i < numStrips; i++) { std::vector strip; - nif->getUShorts(strip, lengths); + nif->getUShorts(strip, lengths[i]); strips.emplace_back(strip); } } diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 93429ef93..2f24a4067 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -58,16 +58,25 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsD { const std::vector &vertices = data.vertices; const std::vector> &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(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((strips.size()-2) * strips[0].size())); + int numTriangles = 0; + for (const std::vector& strip : strips) + { + // Each strip with N points contains information about N-2 triangles. + if (strip.size() >= 3) + numTriangles += static_cast(strip.size()-2); + } + mesh.preallocateIndices(static_cast(numTriangles)); // It's triangulation time. Totally not a NifSkope spell ripoff. for (const std::vector& 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(strip.size()); i++) { diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index e10322f46..60644c758 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -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& 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: