Ver Fonte

Merge branch 'master' of github.com:bkaradzic/bgfx

bkaradzic há 13 anos atrás
pai
commit
ec099acbd7
2 ficheiros alterados com 505 adições e 506 exclusões
  1. 2 0
      src/vertexdecl.cpp
  2. 503 506
      tools/geometryc/geometryc.cpp

+ 2 - 0
src/vertexdecl.cpp

@@ -163,6 +163,7 @@ namespace bgfx
 
 		switch (type)
 		{
+		default:
 		case AttribType::Uint8:
 			{
 				uint8_t* packed = (uint8_t*)data;
@@ -279,6 +280,7 @@ namespace bgfx
 
 		switch (type)
 		{
+		default:
 		case AttribType::Uint8:
 			{
 				uint8_t* packed = (uint8_t*)data;

+ 503 - 506
tools/geometryc/geometryc.cpp

@@ -124,28 +124,28 @@ long int fsize(FILE* _file)
 	fseek(_file, pos, SEEK_SET);
 	return size;
 }
-
-void triangleReorder(uint16_t* _indices, uint32_t _numIndices, uint32_t _numVertices, uint16_t _cacheSize)
-{
-	uint16_t* newIndexList = new uint16_t[_numIndices];
-	Forsyth::OptimizeFaces(_indices, _numIndices, _numVertices, newIndexList, _cacheSize);
-	memcpy(_indices, newIndexList, _numIndices*2);
-	delete [] newIndexList;
-}
-
+
+void triangleReorder(uint16_t* _indices, uint32_t _numIndices, uint32_t _numVertices, uint16_t _cacheSize)
+{
+	uint16_t* newIndexList = new uint16_t[_numIndices];
+	Forsyth::OptimizeFaces(_indices, _numIndices, _numVertices, newIndexList, _cacheSize);
+	memcpy(_indices, newIndexList, _numIndices*2);
+	delete [] newIndexList;
+}
+
 void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
 {
-	struct PosTexcoord
-	{
-		float m_x;
-		float m_y;
-		float m_z;
-		float m_pad0;
-		float m_u;
-		float m_v;
-		float m_pad1;
-		float m_pad2;
-	};
+	struct PosTexcoord
+	{
+		float m_x;
+		float m_y;
+		float m_z;
+		float m_pad0;
+		float m_u;
+		float m_v;
+		float m_pad1;
+		float m_pad2;
+	};
 	
 	float* tangents = new float[6*_numVertices];
 	memset(tangents, 0, 6*_numVertices*sizeof(float) );
@@ -417,491 +417,488 @@ int main(int _argc, const char* _argv[])
 	int argc;
 	char* argv[64];
 	const char* next = data;
-	do
-	{
-		next = tokenizeCommandLine(next, commandLine, len, argc, argv, countof(argv), '\n');
-		if (0 < argc)
-		{
-			if (0 == strcmp(argv[0], "#") )
-			{
-				if (2 < argc
-				&&  0 == strcmp(argv[2], "polygons") )
-				{
-				}
-			}
-			else if (0 == strcmp(argv[0], "f") )
-			{
-				Triangle triangle;
-
-				for (uint32_t edge = 0, numEdges = argc-1; edge < numEdges; ++edge)
-				{
-					Index3 index;
-					index.m_texcoord = -1;
-					index.m_normal = -1;
-					index.m_vertexIndex = -1;
-
-					char* vertex = argv[edge+1];
-					char* texcoord = strchr(vertex, '/');
-					if (NULL != texcoord)
-					{
-						*texcoord++ = '\0';
-
-						char* normal = strchr(texcoord, '/');
-						if (NULL != normal)
-						{
-							*normal++ = '\0';
-							index.m_normal = atoi(normal)-1;
-						}
-
-						index.m_texcoord = atoi(texcoord)-1;
-					}
-
-					index.m_position = atoi(vertex)-1;
-
-					uint64_t hash0 = index.m_position;
-					uint64_t hash1 = uint64_t(index.m_texcoord)<<20;
-					uint64_t hash2 = uint64_t(index.m_normal)<<40;
-					uint64_t hash = hash0^hash1^hash2;
-
-					std::pair<Index3Map::iterator, bool> result = indexMap.insert(std::make_pair(hash, index) );
-					if (!result.second)
-					{
-						Index3& oldIndex = result.first->second;
-						BX_UNUSED(oldIndex);
-						BX_CHECK(oldIndex.m_position == index.m_position
-							&& oldIndex.m_texcoord == index.m_texcoord
-							&& oldIndex.m_normal == index.m_normal
-							, "Hash collision!"
-							);
-					}
-
-					switch (edge)
-					{
-					case 0:
-					case 1:
-					case 2:
-						triangle.m_index[edge] = hash;
-						if (2 == edge)
-						{
-							if (ccw)
-							{
-								std::swap(triangle.m_index[1], triangle.m_index[2]);
-							}
-							triangles.push_back(triangle);
-						}
-						break;
-
-					default:
-						if (ccw)
-						{
-							triangle.m_index[2] = triangle.m_index[1];
-							triangle.m_index[1] = hash;
-						}
-						else
-						{
-							triangle.m_index[1] = triangle.m_index[2];
-							triangle.m_index[2] = hash;
-						}
-						triangles.push_back(triangle);
-						break;
-					}
-				}
-			}
-			else if (0 == strcmp(argv[0], "g") )
-			{
-				EXPECT(1 < argc);
-				group.m_name = argv[1];
-			}
-			else if (*argv[0] == 'v')
-			{
-				group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
-				if (0 < group.m_numTriangles)
-				{
-					groups.push_back(group);
-					group.m_startTriangle = (uint32_t)(triangles.size() );
-					group.m_numTriangles = 0;
-				}
-
-				if (0 == strcmp(argv[0], "vn") )
-				{
-					Vector3 normal;
-					normal.x = (float)atof(argv[1]);
-					normal.y = (float)atof(argv[2]);
-					normal.z = (float)atof(argv[3]);
-
-					normals.push_back(normal);
-				}
-				else if (0 == strcmp(argv[0], "vp") )
-				{
-					static bool once = true;
-					if (once)
-					{
-						once = false;
-						printf("warning: 'parameter space vertices' are unsupported.\n");
-					}
-				}
-				else if (0 == strcmp(argv[0], "vt") )
-				{
-					Vector3 texcoord;
-					texcoord.x = (float)atof(argv[1]);
-					texcoord.y = 0.0f;
-					texcoord.z = 0.0f;
-					switch (argc)
-					{
-					case 4:
-						texcoord.z = (float)atof(argv[3]);
-						// fallthrough
-					case 3:
-						texcoord.y = (float)atof(argv[2]);
-						break;
-
-					default:
-						break;
-					}
-
-					texcoords.push_back(texcoord);
-				}
-				else
-				{
-					float px = (float)atof(argv[1]);
-					float py = (float)atof(argv[2]);
-					float pz = (float)atof(argv[3]);
-					float pw = 1.0f;
-					if (argc > 4)
-					{
-						pw = (float)atof(argv[4]);
-					}
-
-					float invW = scale/pw;
-					px *= invW;
-					py *= invW;
-					pz *= invW;
-
-					Vector3 pos;
-					pos.x = px;
-					pos.y = py;
-					pos.z = pz;
-
-					positions.push_back(pos);
-				}
-			}
-			else if (0 == strcmp(argv[0], "usemtl") )
-			{
-				std::string material(argv[1]);
-
-				if (material != group.m_material)
-				{
-					group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
-					if (0 < group.m_numTriangles)
-					{
-						groups.push_back(group);
-						group.m_startTriangle = (uint32_t)(triangles.size() );
-						group.m_numTriangles = 0;
-					}
-				}
-
-				group.m_material = material;
-			}
-// unsupported tags
-// 				else if (0 == strcmp(argv[0], "mtllib") )
-// 				{
-// 				}
-// 				else if (0 == strcmp(argv[0], "o") )
-// 				{
-// 				}
-// 				else if (0 == strcmp(argv[0], "s") )
-// 				{
-// 				}
-		}
-
-		++num;
-	}
-	while ('\0' != *next);
-
-	group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
-	if (0 < group.m_numTriangles)
-	{
-		groups.push_back(group);
-		group.m_startTriangle = (uint32_t)(triangles.size() );
-		group.m_numTriangles = 0;
-	}
-
-	delete [] data;
-
-	int64_t now = bx::getHPCounter();
-	parseElapsed += now;
-	int64_t convertElapsed = -now;
-
-	struct GroupSortByMaterial
-	{
-		bool operator()(const Group& _lhs, const Group& _rhs)
-		{
-			return _lhs.m_material < _rhs.m_material;
-		}
-	};
-
-	std::sort(groups.begin(), groups.end(), GroupSortByMaterial() );
-
-	bool hasColor = false;
-	bool hasNormal;
-	bool hasTexcoord;
-	{
-		Index3Map::const_iterator it = indexMap.begin();
-		hasNormal = -1 != it->second.m_normal;
-		hasTexcoord = -1 != it->second.m_texcoord;
-
-		if (!hasTexcoord
-		&&  texcoords.size() == positions.size() )
-		{
-			hasTexcoord = true;
-
-			for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it)
-			{
-				it->second.m_texcoord = it->second.m_position;
-			}
-		}
-
-		if (!hasNormal
-		&&  normals.size() == positions.size() )
-		{
-			hasNormal = true;
-
-			for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it)
-			{
-				it->second.m_normal = it->second.m_position;
-			}
-		}
-	}
-
-	bgfx::VertexDecl decl;
-	decl.begin();
-	decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
-
-	if (hasColor)
-	{
-		decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
-	}
-
-	if (hasTexcoord)
-	{
-		switch (packUv)
-		{
-		default:
-		case 0:
-			decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
-			break;
-
-		case 1:
-			decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Half);
-			break;
-		}
-	}
-
-	if (hasNormal)
-	{
-		hasTangent &= hasTexcoord;
-
-		switch (packNormal)
-		{
-		default:
-		case 0:
-			decl.add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float);
-			if (hasTangent)
-			{
-				decl.add(bgfx::Attrib::Tangent, 3, bgfx::AttribType::Float);
-			}
-			break;
-
-		case 1:
-			decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true);
-			if (hasTangent)
-			{
-				decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true);
-			}
-			break;
-		}
-	}
-	decl.end();
-
-	uint32_t stride = decl.getStride();
-	uint8_t* vertexData = new uint8_t[triangles.size() * 3 * stride];
-	uint16_t* indexData = new uint16_t[triangles.size() * 3];
-	int32_t numVertices = 0;
-	int32_t numIndices = 0;
-	int32_t numPrimitives = 0;
-
-	uint8_t* vertices = vertexData;
-	uint16_t* indices = indexData;
-
-	std::string material = groups.begin()->m_material;
-
-	PrimitiveArray primitives;
-
-	bx::CrtFileWriter writer;
-	if (0 != writer.open(outFilePath) )
-	{
-		printf("Unable to open output file '%s'.", outFilePath);
-		exit(EXIT_FAILURE);
-	}
-
-	Primitive prim;
-	prim.m_startVertex = 0;
-	prim.m_startIndex = 0;
-
-	uint32_t positionOffset = decl.getOffset(bgfx::Attrib::Position);
-	uint32_t color0Offset = decl.getOffset(bgfx::Attrib::Color0);
-	uint32_t normalOffset = decl.getOffset(bgfx::Attrib::Normal);
-	uint32_t tangentOffset = decl.getOffset(bgfx::Attrib::Tangent);
-	uint32_t texcoord0Offset = decl.getOffset(bgfx::Attrib::TexCoord0);
-
-	uint32_t ii = 0;
-	for (GroupArray::const_iterator groupIt = groups.begin(); groupIt != groups.end(); ++groupIt, ++ii)
-	{
-		for (uint32_t tri = groupIt->m_startTriangle, end = tri + groupIt->m_numTriangles; tri < end; ++tri)
-		{
-			if (material != groupIt->m_material
-			||  65533 < numVertices)
-			{
-				prim.m_numVertices = numVertices - prim.m_startVertex;
-				prim.m_numIndices = numIndices - prim.m_startIndex;
-				if (0 < prim.m_numVertices)
-				{
-					primitives.push_back(prim);
-				}
-
-				triReorderElapsed -= bx::getHPCounter();
-				for (PrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
-				{
-					const Primitive& prim = *primIt;
-					triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32);
-				}
-				triReorderElapsed += bx::getHPCounter();
-
-				if (hasTangent)
-				{
+	do
+	{
+		next = tokenizeCommandLine(next, commandLine, len, argc, argv, countof(argv), '\n');
+		if (0 < argc)
+		{
+			if (0 == strcmp(argv[0], "#") )
+			{
+				if (2 < argc
+				&&  0 == strcmp(argv[2], "polygons") )
+				{
+				}
+			}
+			else if (0 == strcmp(argv[0], "f") )
+			{
+				Triangle triangle;
+
+				for (uint32_t edge = 0, numEdges = argc-1; edge < numEdges; ++edge)
+				{
+					Index3 index;
+					index.m_texcoord = -1;
+					index.m_normal = -1;
+					index.m_vertexIndex = -1;
+
+					char* vertex = argv[edge+1];
+					char* texcoord = strchr(vertex, '/');
+					if (NULL != texcoord)
+					{
+						*texcoord++ = '\0';
+
+						char* normal = strchr(texcoord, '/');
+						if (NULL != normal)
+						{
+							*normal++ = '\0';
+							index.m_normal = atoi(normal)-1;
+						}
+
+						index.m_texcoord = atoi(texcoord)-1;
+					}
+
+					index.m_position = atoi(vertex)-1;
+
+					uint64_t hash0 = index.m_position;
+					uint64_t hash1 = uint64_t(index.m_texcoord)<<20;
+					uint64_t hash2 = uint64_t(index.m_normal)<<40;
+					uint64_t hash = hash0^hash1^hash2;
+
+					std::pair<Index3Map::iterator, bool> result = indexMap.insert(std::make_pair(hash, index) );
+					if (!result.second)
+					{
+						Index3& oldIndex = result.first->second;
+						BX_UNUSED(oldIndex);
+						BX_CHECK(oldIndex.m_position == index.m_position
+							&& oldIndex.m_texcoord == index.m_texcoord
+							&& oldIndex.m_normal == index.m_normal
+							, "Hash collision!"
+							);
+					}
+
+					switch (edge)
+					{
+					case 0:
+					case 1:
+					case 2:
+						triangle.m_index[edge] = hash;
+						if (2 == edge)
+						{
+							if (ccw)
+							{
+								std::swap(triangle.m_index[1], triangle.m_index[2]);
+							}
+							triangles.push_back(triangle);
+						}
+						break;
+
+					default:
+						if (ccw)
+						{
+							triangle.m_index[2] = triangle.m_index[1];
+							triangle.m_index[1] = hash;
+						}
+						else
+						{
+							triangle.m_index[1] = triangle.m_index[2];
+							triangle.m_index[2] = hash;
+						}
+						triangles.push_back(triangle);
+						break;
+					}
+				}
+			}
+			else if (0 == strcmp(argv[0], "g") )
+			{
+				EXPECT(1 < argc);
+				group.m_name = argv[1];
+			}
+			else if (*argv[0] == 'v')
+			{
+				group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
+				if (0 < group.m_numTriangles)
+				{
+					groups.push_back(group);
+					group.m_startTriangle = (uint32_t)(triangles.size() );
+					group.m_numTriangles = 0;
+				}
+
+				if (0 == strcmp(argv[0], "vn") )
+				{
+					Vector3 normal;
+					normal.x = (float)atof(argv[1]);
+					normal.y = (float)atof(argv[2]);
+					normal.z = (float)atof(argv[3]);
+
+					normals.push_back(normal);
+				}
+				else if (0 == strcmp(argv[0], "vp") )
+				{
+					static bool once = true;
+					if (once)
+					{
+						once = false;
+						printf("warning: 'parameter space vertices' are unsupported.\n");
+					}
+				}
+				else if (0 == strcmp(argv[0], "vt") )
+				{
+					Vector3 texcoord;
+					texcoord.x = (float)atof(argv[1]);
+					texcoord.y = 0.0f;
+					texcoord.z = 0.0f;
+					switch (argc)
+					{
+					case 4:
+						texcoord.z = (float)atof(argv[3]);
+						// fallthrough
+					case 3:
+						texcoord.y = (float)atof(argv[2]);
+						break;
+
+					default:
+						break;
+					}
+
+					texcoords.push_back(texcoord);
+				}
+				else
+				{
+					float px = (float)atof(argv[1]);
+					float py = (float)atof(argv[2]);
+					float pz = (float)atof(argv[3]);
+					float pw = 1.0f;
+					if (argc > 4)
+					{
+						pw = (float)atof(argv[4]);
+					}
+
+					float invW = scale/pw;
+					px *= invW;
+					py *= invW;
+					pz *= invW;
+
+					Vector3 pos;
+					pos.x = px;
+					pos.y = py;
+					pos.z = pz;
+
+					positions.push_back(pos);
+				}
+			}
+			else if (0 == strcmp(argv[0], "usemtl") )
+			{
+				std::string material(argv[1]);
+
+				if (material != group.m_material)
+				{
+					group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
+					if (0 < group.m_numTriangles)
+					{
+						groups.push_back(group);
+						group.m_startTriangle = (uint32_t)(triangles.size() );
+						group.m_numTriangles = 0;
+					}
+				}
+
+				group.m_material = material;
+			}
+// unsupported tags
+// 				else if (0 == strcmp(argv[0], "mtllib") )
+// 				{
+// 				}
+// 				else if (0 == strcmp(argv[0], "o") )
+// 				{
+// 				}
+// 				else if (0 == strcmp(argv[0], "s") )
+// 				{
+// 				}
+		}
+
+		++num;
+	}
+	while ('\0' != *next);
+
+	group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
+	if (0 < group.m_numTriangles)
+	{
+		groups.push_back(group);
+		group.m_startTriangle = (uint32_t)(triangles.size() );
+		group.m_numTriangles = 0;
+	}
+
+	delete [] data;
+
+	int64_t now = bx::getHPCounter();
+	parseElapsed += now;
+	int64_t convertElapsed = -now;
+
+	struct GroupSortByMaterial
+	{
+		bool operator()(const Group& _lhs, const Group& _rhs)
+		{
+			return _lhs.m_material < _rhs.m_material;
+		}
+	};
+
+	std::sort(groups.begin(), groups.end(), GroupSortByMaterial() );
+
+	bool hasColor = false;
+	bool hasNormal;
+	bool hasTexcoord;
+	{
+		Index3Map::const_iterator it = indexMap.begin();
+		hasNormal = -1 != it->second.m_normal;
+		hasTexcoord = -1 != it->second.m_texcoord;
+
+		if (!hasTexcoord
+		&&  texcoords.size() == positions.size() )
+		{
+			hasTexcoord = true;
+
+			for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it)
+			{
+				it->second.m_texcoord = it->second.m_position;
+			}
+		}
+
+		if (!hasNormal
+		&&  normals.size() == positions.size() )
+		{
+			hasNormal = true;
+
+			for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it)
+			{
+				it->second.m_normal = it->second.m_position;
+			}
+		}
+	}
+
+	bgfx::VertexDecl decl;
+	decl.begin();
+	decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
+
+	if (hasColor)
+	{
+		decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
+	}
+
+	if (hasTexcoord)
+	{
+		switch (packUv)
+		{
+		default:
+		case 0:
+			decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
+			break;
+
+		case 1:
+			decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Half);
+			break;
+		}
+	}
+
+	if (hasNormal)
+	{
+		hasTangent &= hasTexcoord;
+
+		switch (packNormal)
+		{
+		default:
+		case 0:
+			decl.add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float);
+			if (hasTangent)
+			{
+				decl.add(bgfx::Attrib::Tangent, 3, bgfx::AttribType::Float);
+			}
+			break;
+
+		case 1:
+			decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true);
+			if (hasTangent)
+			{
+				decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true);
+			}
+			break;
+		}
+	}
+	decl.end();
+
+	uint32_t stride = decl.getStride();
+	uint8_t* vertexData = new uint8_t[triangles.size() * 3 * stride];
+	uint16_t* indexData = new uint16_t[triangles.size() * 3];
+	int32_t numVertices = 0;
+	int32_t numIndices = 0;
+	int32_t numPrimitives = 0;
+
+	uint8_t* vertices = vertexData;
+	uint16_t* indices = indexData;
+
+	std::string material = groups.begin()->m_material;
+
+	PrimitiveArray primitives;
+
+	bx::CrtFileWriter writer;
+	if (0 != writer.open(outFilePath) )
+	{
+		printf("Unable to open output file '%s'.", outFilePath);
+		exit(EXIT_FAILURE);
+	}
+
+	Primitive prim;
+	prim.m_startVertex = 0;
+	prim.m_startIndex = 0;
+
+	uint32_t positionOffset = decl.getOffset(bgfx::Attrib::Position);
+	uint32_t color0Offset = decl.getOffset(bgfx::Attrib::Color0);
+
+	uint32_t ii = 0;
+	for (GroupArray::const_iterator groupIt = groups.begin(); groupIt != groups.end(); ++groupIt, ++ii)
+	{
+		for (uint32_t tri = groupIt->m_startTriangle, end = tri + groupIt->m_numTriangles; tri < end; ++tri)
+		{
+			if (material != groupIt->m_material
+			||  65533 < numVertices)
+			{
+				prim.m_numVertices = numVertices - prim.m_startVertex;
+				prim.m_numIndices = numIndices - prim.m_startIndex;
+				if (0 < prim.m_numVertices)
+				{
+					primitives.push_back(prim);
+				}
+
+				triReorderElapsed -= bx::getHPCounter();
+				for (PrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
+				{
+					const Primitive& prim = *primIt;
+					triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32);
+				}
+				triReorderElapsed += bx::getHPCounter();
+
+				if (hasTangent)
+				{
 					calcTangents(vertexData, numVertices, decl, indexData, numIndices);
-				}
-
-				write(&writer, vertexData, numVertices, decl, indexData, numIndices, material, primitives);
-				primitives.clear();
-
-				for (Index3Map::iterator indexIt = indexMap.begin(); indexIt != indexMap.end(); ++indexIt)
-				{
-					indexIt->second.m_vertexIndex = -1;
-				}
-
-				vertices = vertexData;
-				indices = indexData;
-				numVertices = 0;
-				numIndices = 0;
-				prim.m_startVertex = 0;
-				prim.m_startIndex = 0;
-				++numPrimitives;
-
-				material = groupIt->m_material;
-			}
-
-			Triangle& triangle = triangles[tri];
-			for (uint32_t edge = 0; edge < 3; ++edge)
-			{
-				uint64_t hash = triangle.m_index[edge];
-				Index3& index = indexMap[hash];
-				if (index.m_vertexIndex == -1)
-				{
-		 			index.m_vertexIndex = numVertices++;
-
-					float* position = (float*)(vertices + positionOffset);
-					memcpy(position, &positions[index.m_position], 3*sizeof(float) );
-
-					if (hasColor)
-					{
-						uint32_t* color0 = (uint32_t*)(vertices + color0Offset);
-						*color0 = rgbaToAbgr(numVertices%255, numIndices%255, 0, 0xff);
-					}
-
-					if (hasTexcoord)
-					{
-						float uv[2];
-						memcpy(uv, &texcoords[index.m_texcoord], 2*sizeof(float) );
-
-						if (flipV)
-						{
-							uv[1] = -uv[1];
-						}
-
-						bgfx::vertexPack(uv, true, bgfx::Attrib::TexCoord0, decl, vertices);
-					}
-
-					if (hasNormal)
-					{
-						float normal[4];
-						vec3Norm(normal, (float*)&normals[index.m_normal]);
-						bgfx::vertexPack(normal, true, bgfx::Attrib::Normal, decl, vertices);
-					}
-
-					vertices += stride;
-				}
-
-				*indices++ = (uint16_t)index.m_vertexIndex;
-				++numIndices;
-			}
-		}
-
-		if (0 < numVertices)
-		{
-			prim.m_numVertices = numVertices - prim.m_startVertex;
-			prim.m_numIndices = numIndices - prim.m_startIndex;
-			prim.m_name = groupIt->m_name;
-			primitives.push_back(prim);
-			prim.m_startVertex = numVertices;
-			prim.m_startIndex = numIndices;
-		}
-
-		BX_TRACE("%3d: s %5d, n %5d, %s\n"
-			, ii
-			, groupIt->m_startTriangle
-			, groupIt->m_numTriangles
-			, groupIt->m_material.c_str()
-			);
-	}
-
-	if (0 < primitives.size() )
-	{
-		triReorderElapsed -= bx::getHPCounter();
-		for (PrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
-		{
-			const Primitive& prim = *primIt;
-			triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32);
-		}
-		triReorderElapsed += bx::getHPCounter();
-
-		if (hasTangent)
-		{
+				}
+
+				write(&writer, vertexData, numVertices, decl, indexData, numIndices, material, primitives);
+				primitives.clear();
+
+				for (Index3Map::iterator indexIt = indexMap.begin(); indexIt != indexMap.end(); ++indexIt)
+				{
+					indexIt->second.m_vertexIndex = -1;
+				}
+
+				vertices = vertexData;
+				indices = indexData;
+				numVertices = 0;
+				numIndices = 0;
+				prim.m_startVertex = 0;
+				prim.m_startIndex = 0;
+				++numPrimitives;
+
+				material = groupIt->m_material;
+			}
+
+			Triangle& triangle = triangles[tri];
+			for (uint32_t edge = 0; edge < 3; ++edge)
+			{
+				uint64_t hash = triangle.m_index[edge];
+				Index3& index = indexMap[hash];
+				if (index.m_vertexIndex == -1)
+				{
+		 			index.m_vertexIndex = numVertices++;
+
+					float* position = (float*)(vertices + positionOffset);
+					memcpy(position, &positions[index.m_position], 3*sizeof(float) );
+
+					if (hasColor)
+					{
+						uint32_t* color0 = (uint32_t*)(vertices + color0Offset);
+						*color0 = rgbaToAbgr(numVertices%255, numIndices%255, 0, 0xff);
+					}
+
+					if (hasTexcoord)
+					{
+						float uv[2];
+						memcpy(uv, &texcoords[index.m_texcoord], 2*sizeof(float) );
+
+						if (flipV)
+						{
+							uv[1] = -uv[1];
+						}
+
+						bgfx::vertexPack(uv, true, bgfx::Attrib::TexCoord0, decl, vertices);
+					}
+
+					if (hasNormal)
+					{
+						float normal[4];
+						vec3Norm(normal, (float*)&normals[index.m_normal]);
+						bgfx::vertexPack(normal, true, bgfx::Attrib::Normal, decl, vertices);
+					}
+
+					vertices += stride;
+				}
+
+				*indices++ = (uint16_t)index.m_vertexIndex;
+				++numIndices;
+			}
+		}
+
+		if (0 < numVertices)
+		{
+			prim.m_numVertices = numVertices - prim.m_startVertex;
+			prim.m_numIndices = numIndices - prim.m_startIndex;
+			prim.m_name = groupIt->m_name;
+			primitives.push_back(prim);
+			prim.m_startVertex = numVertices;
+			prim.m_startIndex = numIndices;
+		}
+
+		BX_TRACE("%3d: s %5d, n %5d, %s\n"
+			, ii
+			, groupIt->m_startTriangle
+			, groupIt->m_numTriangles
+			, groupIt->m_material.c_str()
+			);
+	}
+
+	if (0 < primitives.size() )
+	{
+		triReorderElapsed -= bx::getHPCounter();
+		for (PrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
+		{
+			const Primitive& prim = *primIt;
+			triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32);
+		}
+		triReorderElapsed += bx::getHPCounter();
+
+		if (hasTangent)
+		{
 			calcTangents(vertexData, numVertices, decl, indexData, numIndices);
-		}
-
-		write(&writer, vertexData, numVertices, decl, indexData, numIndices, material, primitives);
-	}
-
-	printf("size: %d\n", writer.seek() );
-	writer.close();
-
-	delete [] indexData;
-	delete [] vertexData;
-
-	now = bx::getHPCounter();
-	convertElapsed += now;
-
-	printf("parse %f [s]\ntri reorder %f [s]\nconvert %f [s]\n# %d, g %d, p %d, v %d, i %d\n"
-		, double(parseElapsed)/bx::getHPFrequency()
-		, double(triReorderElapsed)/bx::getHPFrequency()
-		, double(convertElapsed)/bx::getHPFrequency()
-		, num
-		, groups.size()
-		, numPrimitives
-		, numVertices
-		, numIndices
-		);
-
-	return EXIT_SUCCESS;
-}
+		}
+
+		write(&writer, vertexData, numVertices, decl, indexData, numIndices, material, primitives);
+	}
+
+	printf("size: %d\n", uint32_t(writer.seek() ) );
+	writer.close();
+
+	delete [] indexData;
+	delete [] vertexData;
+
+	now = bx::getHPCounter();
+	convertElapsed += now;
+
+	printf("parse %f [s]\ntri reorder %f [s]\nconvert %f [s]\n# %d, g %d, p %d, v %d, i %d\n"
+		, double(parseElapsed)/bx::getHPFrequency()
+		, double(triReorderElapsed)/bx::getHPFrequency()
+		, double(convertElapsed)/bx::getHPFrequency()
+		, num
+		, uint32_t(groups.size() )
+		, numPrimitives
+		, numVertices
+		, numIndices
+		);
+
+	return EXIT_SUCCESS;
+}