From e568c2df9dbfe82355d5d61642be7b7a96e1cb89 Mon Sep 17 00:00:00 2001 From: Johannes Ebersold Date: Wed, 19 Nov 2014 14:38:03 +0100 Subject: [PATCH] ColladaParser::ReadIndexData: don't rely on the specified number of primitives. Especially TriStrips don't specify triangle count upfront, so one needs to sum up the count of triangles read from all

tags in a tristrip collection. --- code/ColladaParser.cpp | 18 ++++++++++++++---- code/ColladaParser.h | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index b6fd73dfa..b199ccc52 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -1867,14 +1867,15 @@ void ColladaParser::ReadIndexData( Mesh* pMesh) // read primitive count from the attribute int attrCount = GetAttribute( "count"); size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount); + // some mesh types (e.g. tristrips) don't specify primitive count upfront, + // so we need to sum up the actual number of primitives while we read the

-tags + size_t actualPrimitives = 0; // material subgroup int attrMaterial = TestAttribute( "material"); SubMesh subgroup; if( attrMaterial > -1) subgroup.mMaterial = mReader->getAttributeValue( attrMaterial); - subgroup.mNumFaces = numPrimitives; - pMesh->mSubMeshes.push_back( subgroup); // distinguish between polys and triangles std::string elementName = mReader->getNodeName(); @@ -1933,7 +1934,7 @@ void ColladaParser::ReadIndexData( Mesh* pMesh) if( !mReader->isEmptyElement()) { // now here the actual fun starts - these are the indices to construct the mesh data from - ReadPrimitives( pMesh, perIndexData, numPrimitives, vcount, primType); + actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType); } } else { @@ -1948,6 +1949,14 @@ void ColladaParser::ReadIndexData( Mesh* pMesh) break; } } + + // small sanity check + if (primType != Prim_TriFans && primType != Prim_TriStrips) + ai_assert(actualPrimitives == numPrimitives); + + // only when we're done reading all

tags (and thus know the final vertex count) can we commit the submesh + subgroup.mNumFaces = actualPrimitives; + pMesh->mSubMeshes.push_back(subgroup); } // ------------------------------------------------------------------------------------------------ @@ -1995,7 +2004,7 @@ void ColladaParser::ReadInputChannel( std::vector& poChannels) // ------------------------------------------------------------------------------------------------ // Reads a

primitive index list and assembles the mesh data into the given mesh -void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector& pPerIndexChannels, +size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector& pPerIndexChannels, size_t pNumPrimitives, const std::vector& pVCount, PrimitiveType pPrimType) { // determine number of indices coming per vertex @@ -2149,6 +2158,7 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector& pPer // if I ever get my hands on that guy who invented this steaming pile of indirection... TestClosing( "p"); + return numPrimitives; } void ColladaParser::CopyPrimitive(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh* pMesh, std::vector& pPerIndexChannels, size_t currentPrimitive, const std::vector& indices){ diff --git a/code/ColladaParser.h b/code/ColladaParser.h index 9f0963345..931f16ca0 100644 --- a/code/ColladaParser.h +++ b/code/ColladaParser.h @@ -177,7 +177,7 @@ protected: void ReadInputChannel( std::vector& poChannels); /** Reads a

primitive index list and assembles the mesh data into the given mesh */ - void ReadPrimitives( Collada::Mesh* pMesh, std::vector& pPerIndexChannels, + size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector& pPerIndexChannels, size_t pNumPrimitives, const std::vector& pVCount, Collada::PrimitiveType pPrimType); /** Copies the data for a single primitive into the mesh, based on the InputChannels */