|
|
@@ -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;
|
|
|
+}
|