- fix for index overrun when building TexturedTriangleArray

- fix for ws2.0 zero area triangles - drop them when loading
This commit is contained in:
Peter Sadrozinski 2014-12-26 10:24:34 -05:00
parent ddd9691439
commit beeaef3868
2 changed files with 33 additions and 20 deletions

View File

@ -274,6 +274,15 @@ static void read_indices(char* buffer,
if (vaMask & SG_VA_FLOAT_3) vas[7].push_back(*src++); if (vaMask & SG_VA_FLOAT_3) vas[7].push_back(*src++);
} }
} // of elements in the index } // of elements in the index
// WS2.0 fix : toss zero area triangles
if ( ( count == 3 ) && (indexMask & SG_IDX_VERTICES) ) {
if ( (vertices[0] == vertices[1]) ||
(vertices[1] == vertices[2]) ||
(vertices[2] == vertices[0]) ) {
vertices.clear();
}
}
} }
template <class T> template <class T>
@ -468,12 +477,15 @@ void SGBinObject::read_object( gzFile fp,
read_indices<uint16_t>(ptr, nbytes, idx_mask, vertex_attrib_mask, vs, ns, cs, tcs, vas ); read_indices<uint16_t>(ptr, nbytes, idx_mask, vertex_attrib_mask, vs, ns, cs, tcs, vas );
} }
vertices.push_back( vs ); // Fix for WS2.0 - ignore zero area triangles
normals.push_back( ns ); if ( !vs.empty() ) {
colors.push_back( cs ); vertices.push_back( vs );
texCoords.push_back( tcs ); normals.push_back( ns );
vertexAttribs.push_back( vas ); colors.push_back( cs );
materials.push_back( material ); texCoords.push_back( tcs );
vertexAttribs.push_back( vas );
materials.push_back( material );
}
} // of element iteration } // of element iteration
} }

View File

@ -104,34 +104,35 @@ private:
// not an advantage on modern hardware. // not an advantage on modern hardware.
class DrawElementsFacade { class DrawElementsFacade {
public: public:
DrawElementsFacade(unsigned numVerts) : DrawElementsFacade(void) : count(0)
_ushortElements(0), _uintElements(0)
{ {
if (numVerts > 65535) _uintElements = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
_uintElements _ushortElements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES);
= new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
else
_ushortElements
= new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES);
} }
void push_back(unsigned val) void push_back(unsigned val)
{ {
if (_uintElements) count++;
_uintElements->push_back(val); if (count < 65536) {
else
_ushortElements->push_back(val); _ushortElements->push_back(val);
}
_uintElements->push_back(val);
} }
osg::DrawElements* getDrawElements() osg::DrawElements* getDrawElements()
{ {
if (_uintElements) if (count > 65535) {
free (_ushortElements);
return _uintElements; return _uintElements;
return _ushortElements; } else {
free (_uintElements);
return _ushortElements;
}
} }
protected: protected:
osg::DrawElementsUShort* _ushortElements; osg::DrawElementsUShort* _ushortElements;
osg::DrawElementsUInt* _uintElements; osg::DrawElementsUInt* _uintElements;
unsigned count;
}; };
class SGTexturedTriangleBin : public SGTriangleBin<SGVertNormTex> { class SGTexturedTriangleBin : public SGTriangleBin<SGVertNormTex> {
@ -398,7 +399,7 @@ public:
const unsigned invalid = ~unsigned(0); const unsigned invalid = ~unsigned(0);
std::vector<unsigned> indexMap(getNumVertices(), invalid); std::vector<unsigned> indexMap(getNumVertices(), invalid);
DrawElementsFacade deFacade(vertices->size()); DrawElementsFacade deFacade;
for (index_type i = 0; i < triangles.size(); ++i) { for (index_type i = 0; i < triangles.size(); ++i) {
triangle_ref triangle = triangles[i]; triangle_ref triangle = triangles[i];
if (indexMap[triangle[0]] == invalid) { if (indexMap[triangle[0]] == invalid) {