summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/tools/geometryc/geometryc.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/tools/geometryc/geometryc.cpp')
-rw-r--r--3rdparty/bgfx/tools/geometryc/geometryc.cpp552
1 files changed, 268 insertions, 284 deletions
diff --git a/3rdparty/bgfx/tools/geometryc/geometryc.cpp b/3rdparty/bgfx/tools/geometryc/geometryc.cpp
index 1e1f175e102..71eb22547a9 100644
--- a/3rdparty/bgfx/tools/geometryc/geometryc.cpp
+++ b/3rdparty/bgfx/tools/geometryc/geometryc.cpp
@@ -1,25 +1,20 @@
/*
- * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
-#include <stdio.h>
-
#include <algorithm>
-#include <vector>
#include <bx/string.h>
#include <bgfx/bgfx.h>
#include "../../src/vertexdecl.h"
#include <tinystl/allocator.h>
-#include <tinystl/unordered_map.h>
-#include <tinystl/unordered_set.h>
#include <tinystl/string.h>
+#include <tinystl/vector.h>
namespace stl = tinystl;
-#include <forsyth-too/forsythtriangleorderoptimizer.h>
-#include <ib-compress/indexbuffercompression.h>
+#include <meshoptimizer/src/meshoptimizer.h>
#define BGFX_GEOMETRYC_VERSION_MAJOR 1
#define BGFX_GEOMETRYC_VERSION_MINOR 0
@@ -27,7 +22,7 @@ namespace stl = tinystl;
#if 0
# define BX_TRACE(_format, ...) \
do { \
- printf(BX_FILE_LINE_LITERAL "BGFX " _format "\n", ##__VA_ARGS__); \
+ bx::printf(BX_FILE_LINE_LITERAL "BGFX " _format "\n", ##__VA_ARGS__); \
} while(0)
# define BX_WARN(_condition, _format, ...) \
@@ -59,32 +54,22 @@ namespace stl = tinystl;
#include "bounds.h"
-struct Vector3
-{
- float x;
- float y;
- float z;
-};
-
-typedef std::vector<Vector3> Vector3Array;
+typedef stl::vector<bx::Vec3> Vec3Array;
struct Index3
{
int32_t m_position;
int32_t m_texcoord;
int32_t m_normal;
- int32_t m_vertexIndex;
int32_t m_vbc; // Barycentric ID. Holds eigher 0, 1 or 2.
};
-typedef stl::unordered_map<uint64_t, Index3> Index3Map;
-
-struct Triangle
+struct TriIndices
{
- uint64_t m_index[3];
+ Index3 m_index[3];
};
-typedef std::vector<Triangle> TriangleArray;
+typedef stl::vector<TriIndices> TriangleArray;
struct Group
{
@@ -94,7 +79,7 @@ struct Group
stl::string m_material;
};
-typedef std::vector<Group> GroupArray;
+typedef stl::vector<Group> GroupArray;
struct Primitive
{
@@ -105,62 +90,67 @@ struct Primitive
stl::string m_name;
};
-typedef std::vector<Primitive> PrimitiveArray;
+typedef stl::vector<Primitive> PrimitiveArray;
static uint32_t s_obbSteps = 17;
#define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x1)
+#define BGFX_CHUNK_MAGIC_VBC BX_MAKEFOURCC('V', 'B', 'C', 0x0)
#define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0)
-#define BGFX_CHUNK_MAGIC_IBC BX_MAKEFOURCC('I', 'B', 'C', 0x0)
+#define BGFX_CHUNK_MAGIC_IBC BX_MAKEFOURCC('I', 'B', 'C', 0x1)
#define BGFX_CHUNK_MAGIC_PRI BX_MAKEFOURCC('P', 'R', 'I', 0x0)
-long int fsize(FILE* _file)
+void optimizeVertexCache(uint16_t* _indices, uint32_t _numIndices, uint32_t _numVertices)
{
- long int pos = ftell(_file);
- fseek(_file, 0L, SEEK_END);
- long int size = ftell(_file);
- fseek(_file, pos, SEEK_SET);
- return size;
+ uint16_t* newIndexList = new uint16_t[_numIndices];
+ meshopt_optimizeVertexCache(newIndexList, _indices, _numIndices, _numVertices);
+ bx::memCopy(_indices, newIndexList, _numIndices * 2);
+ delete[] newIndexList;
}
-void triangleReorder(uint16_t* _indices, uint32_t _numIndices, uint32_t _numVertices, uint16_t _cacheSize)
+uint32_t optimizeVertexFetch(uint16_t* _indices, uint32_t _numIndices, uint8_t* _vertexData, uint32_t _numVertices, uint16_t _stride)
{
- uint16_t* newIndexList = new uint16_t[_numIndices];
- Forsyth::OptimizeFaces(_indices, _numIndices, _numVertices, 0, newIndexList, _cacheSize);
- bx::memCopy(_indices, newIndexList, _numIndices*2);
- delete [] newIndexList;
+ unsigned char* newVertices = (unsigned char*)malloc(_numVertices * _stride );
+ size_t vertexCount = meshopt_optimizeVertexFetch(newVertices, _indices, _numIndices, _vertexData, _numVertices, _stride);
+ bx::memCopy(_vertexData, newVertices, _numVertices * _stride);
+ free(newVertices);
+
+ return uint32_t(vertexCount);
}
-void triangleCompress(bx::WriterI* _writer, uint16_t* _indices, uint32_t _numIndices, uint8_t* _vertexData, uint32_t _numVertices, uint16_t _stride)
+void writeCompressedIndices(bx::WriterI* _writer, const uint16_t* _indices, uint32_t _numIndices, uint32_t _numVertices)
{
- uint32_t* vertexRemap = (uint32_t*)malloc(_numVertices*sizeof(uint32_t) );
-
- WriteBitstream writer;
- CompressIndexBuffer(_indices, _numIndices/3, vertexRemap, _numVertices, IBCF_AUTO, writer);
- writer.Finish();
- printf( "uncompressed: %10d, compressed: %10d, ratio: %0.2f%%\n"
+ size_t maxSize = meshopt_encodeIndexBufferBound(_numIndices, _numVertices);
+ unsigned char* compressedIndices = (unsigned char*)malloc(maxSize);
+ size_t compressedSize = meshopt_encodeIndexBuffer(compressedIndices, maxSize, _indices, _numIndices);
+ bx::printf( "indices uncompressed: %10d, compressed: %10d, ratio: %0.2f%%\n"
, _numIndices*2
- , (uint32_t)writer.ByteSize()
- , 100.0f - float(writer.ByteSize() ) / float(_numIndices*2)*100.0f
+ , (uint32_t)compressedSize
+ , 100.0f - float(compressedSize ) / float(_numIndices*2)*100.0f
);
- BX_UNUSED(_vertexData, _stride);
- uint8_t* outVertexData = (uint8_t*)malloc(_numVertices*_stride);
- for (uint32_t ii = 0; ii < _numVertices; ++ii)
- {
- uint32_t remap = vertexRemap[ii];
- remap = UINT32_MAX == remap ? ii : remap;
- bx::memCopy(&outVertexData[remap*_stride], &_vertexData[ii*_stride], _stride);
- }
- bx::memCopy(_vertexData, outVertexData, _numVertices*_stride);
- free(outVertexData);
+ bx::write(_writer, (uint32_t)compressedSize);
+ bx::write(_writer, compressedIndices, (uint32_t)compressedSize );
+ free(compressedIndices);
+}
- free(vertexRemap);
+void writeCompressedVertices(bx::WriterI* _writer, const uint8_t* _vertices, uint32_t _numVertices, uint16_t _stride)
+{
+ size_t maxSize = meshopt_encodeVertexBufferBound(_numVertices, _stride);
+ unsigned char* compressedVertices = (unsigned char*)malloc(maxSize);
+ size_t compressedSize = meshopt_encodeVertexBuffer(compressedVertices, maxSize, _vertices, _numVertices, _stride);
+ bx::printf("vertices uncompressed: %10d, compressed: %10d, ratio: %0.2f%%\n"
+ , _numVertices * _stride
+ , (uint32_t)compressedSize
+ , 100.0f - float(compressedSize) / float(_numVertices * _stride)*100.0f
+ );
- bx::write(_writer, writer.RawData(), (uint32_t)writer.ByteSize() );
+ bx::write(_writer, (uint32_t)compressedSize);
+ bx::write(_writer, compressedVertices, (uint32_t)compressedSize );
+ free(compressedVertices);
}
-void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
+void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexLayout _layout, const uint16_t* _indices, uint32_t _numIndices)
{
struct PosTexcoord
{
@@ -188,14 +178,14 @@ void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl
uint32_t i1 = indices[1];
uint32_t i2 = indices[2];
- bgfx::vertexUnpack(&v0.m_x, bgfx::Attrib::Position, _decl, _vertices, i0);
- bgfx::vertexUnpack(&v0.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i0);
+ bgfx::vertexUnpack(&v0.m_x, bgfx::Attrib::Position, _layout, _vertices, i0);
+ bgfx::vertexUnpack(&v0.m_u, bgfx::Attrib::TexCoord0, _layout, _vertices, i0);
- bgfx::vertexUnpack(&v1.m_x, bgfx::Attrib::Position, _decl, _vertices, i1);
- bgfx::vertexUnpack(&v1.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i1);
+ bgfx::vertexUnpack(&v1.m_x, bgfx::Attrib::Position, _layout, _vertices, i1);
+ bgfx::vertexUnpack(&v1.m_u, bgfx::Attrib::TexCoord0, _layout, _vertices, i1);
- bgfx::vertexUnpack(&v2.m_x, bgfx::Attrib::Position, _decl, _vertices, i2);
- bgfx::vertexUnpack(&v2.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i2);
+ bgfx::vertexUnpack(&v2.m_x, bgfx::Attrib::Position, _layout, _vertices, i2);
+ bgfx::vertexUnpack(&v2.m_u, bgfx::Attrib::TexCoord0, _layout, _vertices, i2);
const float bax = v1.m_x - v0.m_x;
const float bay = v1.m_y - v0.m_y;
@@ -236,26 +226,22 @@ void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl
for (uint32_t ii = 0; ii < _numVertices; ++ii)
{
- const float* tanu = &tangents[ii*6];
- const float* tanv = &tangents[ii*6 + 3];
-
- float normal[4];
- bgfx::vertexUnpack(normal, bgfx::Attrib::Normal, _decl, _vertices, ii);
- float ndt = bx::vec3Dot(normal, tanu);
+ const bx::Vec3 tanu = bx::load<bx::Vec3>(&tangents[ii*6]);
+ const bx::Vec3 tanv = bx::load<bx::Vec3>(&tangents[ii*6 + 3]);
- float nxt[3];
- bx::vec3Cross(nxt, normal, tanu);
+ float nxyzw[4];
+ bgfx::vertexUnpack(nxyzw, bgfx::Attrib::Normal, _layout, _vertices, ii);
- float tmp[3];
- tmp[0] = tanu[0] - normal[0] * ndt;
- tmp[1] = tanu[1] - normal[1] * ndt;
- tmp[2] = tanu[2] - normal[2] * ndt;
+ const bx::Vec3 normal = bx::load<bx::Vec3>(nxyzw);
+ const float ndt = bx::dot(normal, tanu);
+ const bx::Vec3 nxt = bx::cross(normal, tanu);
+ const bx::Vec3 tmp = bx::sub(tanu, bx::mul(normal, ndt) );
float tangent[4];
- bx::vec3Norm(tangent, tmp);
+ bx::store(tangent, bx::normalize(tmp) );
+ tangent[3] = bx::dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f;
- tangent[3] = bx::vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f;
- bgfx::vertexPack(tangent, true, bgfx::Attrib::Tangent, _decl, _vertices, ii);
+ bgfx::vertexPack(tangent, true, bgfx::Attrib::Tangent, _layout, _vertices, ii);
}
delete [] tangents;
@@ -269,7 +255,7 @@ void write(bx::WriterI* _writer, const void* _vertices, uint32_t _numVertices, u
Sphere minSphere;
calcMinBoundingSphere(minSphere, _vertices, _numVertices, _stride);
- if (minSphere.m_radius > maxSphere.m_radius)
+ if (minSphere.radius > maxSphere.radius)
{
bx::write(_writer, maxSphere);
}
@@ -290,11 +276,10 @@ void write(bx::WriterI* _writer, const void* _vertices, uint32_t _numVertices, u
void write(bx::WriterI* _writer
, const uint8_t* _vertices
, uint32_t _numVertices
- , const bgfx::VertexDecl& _decl
+ , const bgfx::VertexLayout& _layout
, const uint16_t* _indices
, uint32_t _numIndices
- , const uint8_t* _compressedIndices
- , uint32_t _compressedSize
+ , bool _compress
, const stl::string& _material
, const PrimitiveArray& _primitives
)
@@ -302,21 +287,34 @@ void write(bx::WriterI* _writer
using namespace bx;
using namespace bgfx;
- uint32_t stride = _decl.getStride();
- write(_writer, BGFX_CHUNK_MAGIC_VB);
- write(_writer, _vertices, _numVertices, stride);
+ uint32_t stride = _layout.getStride();
+
+ if (_compress)
+ {
+ write(_writer, BGFX_CHUNK_MAGIC_VBC);
+ write(_writer, _vertices, _numVertices, stride);
+
+ write(_writer, _layout);
+
+ write(_writer, uint16_t(_numVertices) );
+ writeCompressedVertices(_writer, _vertices, _numVertices, uint16_t(stride));
+ }
+ else
+ {
+ write(_writer, BGFX_CHUNK_MAGIC_VB);
+ write(_writer, _vertices, _numVertices, stride);
- write(_writer, _decl);
+ write(_writer, _layout);
- write(_writer, uint16_t(_numVertices) );
- write(_writer, _vertices, _numVertices*stride);
+ write(_writer, uint16_t(_numVertices) );
+ write(_writer, _vertices, _numVertices*stride);
+ }
- if (NULL != _compressedIndices)
+ if (_compress)
{
write(_writer, BGFX_CHUNK_MAGIC_IBC);
write(_writer, _numIndices);
- write(_writer, _compressedSize);
- write(_writer, _compressedIndices, _compressedSize);
+ writeCompressedIndices(_writer, _indices, _numIndices, _numVertices);
}
else
{
@@ -365,20 +363,20 @@ void help(const char* _error = NULL)
{
if (NULL != _error)
{
- fprintf(stderr, "Error:\n%s\n\n", _error);
+ bx::printf("Error:\n%s\n\n", _error);
}
- fprintf(stderr
- , "geometryc, bgfx geometry compiler tool, version %d.%d.%d.\n"
- "Copyright 2011-2018 Branimir Karadzic. All rights reserved.\n"
+ bx::printf(
+ "geometryc, bgfx geometry compiler tool, version %d.%d.%d.\n"
+ "Copyright 2011-2019 Branimir Karadzic. All rights reserved.\n"
"License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause\n\n"
, BGFX_GEOMETRYC_VERSION_MAJOR
, BGFX_GEOMETRYC_VERSION_MINOR
, BGFX_API_VERSION
);
- fprintf(stderr
- , "Usage: geometryc -f <in> -o <out>\n"
+ bx::printf(
+ "Usage: geometryc -f <in> -o <out>\n"
"\n"
"Supported input file types:\n"
@@ -417,8 +415,8 @@ int main(int _argc, const char* _argv[])
if (cmdLine.hasArg('v', "version") )
{
- fprintf(stderr
- , "geometryc, bgfx geometry compiler tool, version %d.%d.%d.\n"
+ bx::printf(
+ "geometryc, bgfx geometry compiler tool, version %d.%d.%d.\n"
, BGFX_GEOMETRYC_VERSION_MAJOR
, BGFX_GEOMETRYC_VERSION_MINOR
, BGFX_API_VERSION
@@ -472,28 +470,29 @@ int main(int _argc, const char* _argv[])
bool hasTangent = cmdLine.hasArg("tangent");
bool hasBc = cmdLine.hasArg("barycentric");
- FILE* file = fopen(filePath, "r");
- if (NULL == file)
+ bx::FileReader fr;
+ if (!bx::open(&fr, filePath) )
{
- printf("Unable to open input file '%s'.", filePath);
+ bx::printf("Unable to open input file '%s'.", filePath);
exit(bx::kExitFailure);
}
int64_t parseElapsed = -bx::getHPCounter();
int64_t triReorderElapsed = 0;
- uint32_t size = (uint32_t)fsize(file);
+ uint32_t size = (uint32_t)bx::getSize(&fr);
char* data = new char[size+1];
- size = (uint32_t)fread(data, 1, size, file);
+ size = bx::read(&fr, data, size);
data[size] = '\0';
- fclose(file);
+ bx::close(&fr);
- // https://en.wikipedia.org/wiki/Wavefront_.obj_file
+ // Reference(s):
+ // - Wavefront .obj file
+ // https://en.wikipedia.org/wiki/Wavefront_.obj_file
- Vector3Array positions;
- Vector3Array normals;
- Vector3Array texcoords;
- Index3Map indexMap;
+ Vec3Array positions;
+ Vec3Array normals;
+ Vec3Array texcoords;
TriangleArray triangles;
GroupArray groups;
@@ -523,8 +522,8 @@ int main(int _argc, const char* _argv[])
}
else if (0 == bx::strCmp(argv[0], "f") )
{
- Triangle triangle;
- bx::memSet(&triangle, 0, sizeof(Triangle) );
+ TriIndices triangle;
+ bx::memSet(&triangle, 0, sizeof(TriIndices) );
const int numNormals = (int)normals.size();
const int numTexcoords = (int)texcoords.size();
@@ -534,14 +533,13 @@ int main(int _argc, const char* _argv[])
Index3 index;
index.m_texcoord = -1;
index.m_normal = -1;
- index.m_vertexIndex = -1;
if (hasBc)
{
index.m_vbc = edge < 3 ? edge : (1+(edge+1) )&1;
}
else
{
- index.m_vbc = 0;
+ index.m_vbc = 0;
}
{
@@ -562,7 +560,9 @@ int main(int _argc, const char* _argv[])
texcoord.set(texcoord.getPtr() + 1, normal.getPtr());
- // https://en.wikipedia.org/wiki/Wavefront_.obj_file#Vertex_Normal_Indices_Without_Texture_Coordinate_Indices
+ // Reference(s):
+ // - Wavefront .obj file / Vertex normal indices without texture coordinate indices
+ // https://en.wikipedia.org/wiki/Wavefront_.obj_file#Vertex_Normal_Indices_Without_Texture_Coordinate_Indices
if (!texcoord.isEmpty())
{
int32_t tex;
@@ -576,34 +576,15 @@ int main(int _argc, const char* _argv[])
index.m_position = (pos < 0) ? pos + numPositions : pos - 1;
}
- const uint64_t hash0 = uint64_t(index.m_position)<< 0;
- const uint64_t hash1 = uint64_t(index.m_texcoord)<<20;
- const uint64_t hash2 = uint64_t(index.m_normal )<<40;
- const uint64_t hash3 = uint64_t(index.m_vbc )<<60;
- const uint64_t hash = hash0^hash1^hash2^hash3;
-
- stl::pair<Index3Map::iterator, bool> result = indexMap.insert(stl::make_pair(hash, index) );
- if (!result.second)
- {
- Index3& oldIndex = result.first->second;
- BX_UNUSED(oldIndex);
- BX_CHECK(true
- && 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;
+ triangle.m_index[edge] = index;
if (2 == edge)
{
if (ccw)
{
- std::swap(triangle.m_index[1], triangle.m_index[2]);
+ bx::swap(triangle.m_index[1], triangle.m_index[2]);
}
triangles.push_back(triangle);
}
@@ -613,12 +594,12 @@ int main(int _argc, const char* _argv[])
if (ccw)
{
triangle.m_index[2] = triangle.m_index[1];
- triangle.m_index[1] = hash;
+ triangle.m_index[1] = index;
}
else
{
triangle.m_index[1] = triangle.m_index[2];
- triangle.m_index[2] = hash;
+ triangle.m_index[2] = index;
}
triangles.push_back(triangle);
@@ -642,7 +623,7 @@ int main(int _argc, const char* _argv[])
if (0 == bx::strCmp(argv[0], "vn") )
{
- Vector3 normal;
+ bx::Vec3 normal;
bx::fromString(&normal.x, argv[1]);
bx::fromString(&normal.y, argv[2]);
bx::fromString(&normal.z, argv[3]);
@@ -655,12 +636,12 @@ int main(int _argc, const char* _argv[])
if (once)
{
once = false;
- printf("warning: 'parameter space vertices' are unsupported.\n");
+ bx::printf("warning: 'parameter space vertices' are unsupported.\n");
}
}
else if (0 == bx::strCmp(argv[0], "vt") )
{
- Vector3 texcoord;
+ bx::Vec3 texcoord;
texcoord.y = 0.0f;
texcoord.z = 0.0f;
@@ -689,7 +670,7 @@ int main(int _argc, const char* _argv[])
bx::fromString(&py, argv[2]);
bx::fromString(&pz, argv[3]);
- if (argc > 4)
+ if (argc == 5 || argc == 8)
{
bx::fromString(&pw, argv[4]);
}
@@ -703,7 +684,7 @@ int main(int _argc, const char* _argv[])
py *= invW;
pz *= invW;
- Vector3 pos;
+ bx::Vec3 pos;
pos.x = px;
pos.y = py;
pos.z = pz;
@@ -763,55 +744,67 @@ int main(int _argc, const char* _argv[])
bool hasNormal;
bool hasTexcoord;
{
- Index3Map::const_iterator it = indexMap.begin();
- hasNormal = -1 != it->second.m_normal;
- hasTexcoord = -1 != it->second.m_texcoord;
+ TriangleArray::const_iterator it = triangles.begin();
+ hasNormal = -1 != it->m_index[0].m_normal;
+ hasTexcoord = -1 != it->m_index[0].m_texcoord;
if (!hasTexcoord)
{
- for (Index3Map::iterator jt = indexMap.begin(), jtEnd = indexMap.end(); jt != jtEnd && !hasTexcoord; ++jt)
+ for (TriangleArray::iterator jt = triangles.begin(), jtEnd = triangles.end(); jt != jtEnd && !hasTexcoord; ++jt)
{
- hasTexcoord |= -1 != jt->second.m_texcoord;
+ for (uint32_t i = 0; i < 3; ++i)
+ {
+ hasTexcoord |= -1 != jt->m_index[i].m_texcoord;
+ }
}
if (hasTexcoord)
{
- for (Index3Map::iterator jt = indexMap.begin(), jtEnd = indexMap.end(); jt != jtEnd; ++jt)
+ for (TriangleArray::iterator jt = triangles.begin(), jtEnd = triangles.end(); jt != jtEnd; ++jt)
{
- jt->second.m_texcoord = -1 == jt->second.m_texcoord ? 0 : jt->second.m_texcoord;
+ for (uint32_t i = 0; i < 3; ++i)
+ {
+ jt->m_index[i].m_texcoord = -1 == jt->m_index[i].m_texcoord ? 0 : jt->m_index[i].m_texcoord;
+ }
}
}
}
if (!hasNormal)
{
- for (Index3Map::iterator jt = indexMap.begin(), jtEnd = indexMap.end(); jt != jtEnd && !hasNormal; ++jt)
+ for (TriangleArray::iterator jt = triangles.begin(), jtEnd = triangles.end(); jt != jtEnd && !hasNormal; ++jt)
{
- hasNormal |= -1 != jt->second.m_normal;
+ for (uint32_t i = 0; i < 3; ++i)
+ {
+ hasNormal |= -1 != jt->m_index[i].m_normal;
+ }
}
if (hasNormal)
{
- for (Index3Map::iterator jt = indexMap.begin(), jtEnd = indexMap.end(); jt != jtEnd; ++jt)
+ for (TriangleArray::iterator jt = triangles.begin(), jtEnd = triangles.end(); jt != jtEnd; ++jt)
{
- jt->second.m_normal = -1 == jt->second.m_normal ? 0 : jt->second.m_normal;
+ for (uint32_t i = 0; i < 3; ++i)
+ {
+ jt->m_index[i].m_normal = -1 == jt->m_index[i].m_normal ? 0 : jt->m_index[i].m_normal;
+ }
}
}
}
}
- bgfx::VertexDecl decl;
- decl.begin();
- decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
+ bgfx::VertexLayout layout;
+ layout.begin();
+ layout.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
if (hasColor)
{
- decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
+ layout.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
}
if (hasBc)
{
- decl.add(bgfx::Attrib::Color1, 4, bgfx::AttribType::Uint8, true);
+ layout.add(bgfx::Attrib::Color1, 4, bgfx::AttribType::Uint8, true);
}
if (hasTexcoord)
@@ -820,11 +813,11 @@ int main(int _argc, const char* _argv[])
{
default:
case 0:
- decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
+ layout.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
break;
case 1:
- decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Half);
+ layout.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Half);
break;
}
}
@@ -837,35 +830,43 @@ int main(int _argc, const char* _argv[])
{
default:
case 0:
- decl.add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float);
+ layout.add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float);
if (hasTangent)
{
- decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Float);
+ layout.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Float);
}
break;
case 1:
- decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true);
+ layout.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true);
if (hasTangent)
{
- decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true);
+ layout.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true);
}
break;
}
}
- decl.end();
+ layout.end();
- uint32_t stride = decl.getStride();
+ uint32_t stride = layout.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;
+
+ int32_t writtenPrimitives = 0;
+ int32_t writtenVertices = 0;
+ int32_t writtenIndices = 0;
uint8_t* vertices = vertexData;
uint16_t* indices = indexData;
-
+
+ const uint32_t tableSize = 65536 * 2;
+ const uint32_t hashmod = tableSize - 1;
+ uint32_t* table = new uint32_t[tableSize];
+ bx::memSet(table, 0xff, tableSize * sizeof(uint32_t));
+
stl::string material = groups.begin()->m_material;
PrimitiveArray primitives;
@@ -873,7 +874,7 @@ int main(int _argc, const char* _argv[])
bx::FileWriter writer;
if (!bx::open(&writer, outFilePath) )
{
- printf("Unable to open output file '%s'.", outFilePath);
+ bx::printf("Unable to open output file '%s'.", outFilePath);
exit(bx::kExitFailure);
}
@@ -881,18 +882,22 @@ int main(int _argc, const char* _argv[])
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 positionOffset = layout.getOffset(bgfx::Attrib::Position);
+ uint32_t color0Offset = layout.getOffset(bgfx::Attrib::Color0);
- bx::DefaultAllocator crtAllocator;
- bx::MemoryBlock memBlock(&crtAllocator);
+ Group sentinelGroup;
+ sentinelGroup.m_startTriangle = 0;
+ sentinelGroup.m_numTriangles = UINT32_MAX;
+ groups.push_back(sentinelGroup);
uint32_t ii = 0;
for (GroupArray::const_iterator groupIt = groups.begin(); groupIt != groups.end(); ++groupIt, ++ii)
{
+ bool sentinel = groupIt->m_startTriangle == 0 && groupIt->m_numTriangles == UINT32_MAX;
for (uint32_t tri = groupIt->m_startTriangle, end = tri + groupIt->m_numTriangles; tri < end; ++tri)
{
if (0 != bx::strCmp(material.c_str(), groupIt->m_material.c_str() )
+ || sentinel
|| 65533 <= numVertices)
{
prim.m_numVertices = numVertices - prim.m_startVertex;
@@ -904,47 +909,36 @@ int main(int _argc, const char* _argv[])
if (hasTangent)
{
- calcTangents(vertexData, uint16_t(numVertices), decl, indexData, numIndices);
+ calcTangents(vertexData, uint16_t(numVertices), layout, indexData, numIndices);
}
- bx::MemoryWriter memWriter(&memBlock);
-
triReorderElapsed -= bx::getHPCounter();
for (PrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
{
const Primitive& prim1 = *primIt;
- triangleReorder(indexData + prim1.m_startIndex, prim1.m_numIndices, numVertices, 32);
- if (compress)
- {
- triangleCompress(
- &memWriter
- , indexData + prim1.m_startIndex
- , prim1.m_numIndices
- , vertexData + prim1.m_startVertex
- , numVertices
- , uint16_t(stride)
- );
- }
+ optimizeVertexCache(indexData + prim1.m_startIndex, prim1.m_numIndices, numVertices);
}
+ numVertices = optimizeVertexFetch(indexData, numIndices, vertexData, numVertices, uint16_t(stride));
+
triReorderElapsed += bx::getHPCounter();
write(&writer
, vertexData
, numVertices
- , decl
+ , layout
, indexData
, numIndices
- , (uint8_t*)memBlock.more()
- , memBlock.getSize()
+ , compress
, material
, primitives
);
primitives.clear();
+
+ bx::memSet(table, 0xff, tableSize * sizeof(uint32_t));
- for (Index3Map::iterator indexIt = indexMap.begin(); indexIt != indexMap.end(); ++indexIt)
- {
- indexIt->second.m_vertexIndex = -1;
- }
+ ++writtenPrimitives;
+ writtenVertices += numVertices;
+ writtenIndices += numIndices;
vertices = vertexData;
indices = indexData;
@@ -952,64 +946,91 @@ int main(int _argc, const char* _argv[])
numIndices = 0;
prim.m_startVertex = 0;
prim.m_startIndex = 0;
- ++numPrimitives;
material = groupIt->m_material;
+
+ if (sentinel)
+ break;
}
- Triangle& triangle = triangles[tri];
+ TriIndices& 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)
+ Index3& index = triangle.m_index[edge];
+
+ float* position = (float*)(vertices + positionOffset);
+ bx::memCopy(position, &positions[index.m_position], 3*sizeof(float) );
+
+ if (hasColor)
{
- index.m_vertexIndex = numVertices++;
-
- float* position = (float*)(vertices + positionOffset);
- bx::memCopy(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 (hasBc)
+ {
+ const float bc[3] =
{
- uint32_t* color0 = (uint32_t*)(vertices + color0Offset);
- *color0 = rgbaToAbgr(numVertices%255, numIndices%255, 0, 0xff);
- }
-
- if (hasBc)
+ (index.m_vbc == 0) ? 1.0f : 0.0f,
+ (index.m_vbc == 1) ? 1.0f : 0.0f,
+ (index.m_vbc == 2) ? 1.0f : 0.0f,
+ };
+ bgfx::vertexPack(bc, true, bgfx::Attrib::Color1, layout, vertices);
+ }
+
+ if (hasTexcoord)
+ {
+ float uv[2];
+ bx::memCopy(uv, &texcoords[index.m_texcoord], 2*sizeof(float) );
+
+ if (flipV)
{
- const float bc[3] =
- {
- (index.m_vbc == 0) ? 1.0f : 0.0f,
- (index.m_vbc == 1) ? 1.0f : 0.0f,
- (index.m_vbc == 2) ? 1.0f : 0.0f,
- };
- bgfx::vertexPack(bc, true, bgfx::Attrib::Color1, decl, vertices);
+ uv[1] = -uv[1];
}
+
+ bgfx::vertexPack(uv, true, bgfx::Attrib::TexCoord0, layout, vertices);
+ }
+
+ if (hasNormal)
+ {
+ float normal[4];
+ bx::store(normal, bx::normalize(bx::load<bx::Vec3>(&normals[index.m_normal]) ) );
+ normal[3] = 0.0f;
+ bgfx::vertexPack(normal, true, bgfx::Attrib::Normal, layout, vertices);
+ }
- if (hasTexcoord)
+ uint32_t hash = bx::hash<bx::HashMurmur2A>(vertices, stride);
+ size_t bucket = hash & hashmod;
+ uint32_t vertexIndex = UINT32_MAX;
+
+ for (size_t probe = 0; probe <= hashmod; ++probe)
+ {
+ uint32_t& item = table[bucket];
+
+ if (item == ~0u)
{
- float uv[2];
- bx::memCopy(uv, &texcoords[index.m_texcoord], 2*sizeof(float) );
-
- if (flipV)
- {
- uv[1] = -uv[1];
- }
-
- bgfx::vertexPack(uv, true, bgfx::Attrib::TexCoord0, decl, vertices);
+ vertices += stride;
+ item = numVertices++;
+ vertexIndex = item;
+ break;
}
-
- if (hasNormal)
+
+ if (0 == bx::memCmp(vertexData + item * stride, vertices, stride))
{
- float normal[4];
- bx::vec3Norm(normal, (float*)&normals[index.m_normal]);
- bgfx::vertexPack(normal, true, bgfx::Attrib::Normal, decl, vertices);
+ vertexIndex = item;
+ break;
}
-
- vertices += stride;
+
+ bucket = (bucket + probe + 1) & hashmod;
}
-
- *indices++ = (uint16_t)index.m_vertexIndex;
+
+ if ( vertexIndex == UINT32_MAX )
+ {
+ bx::printf("hash table insert failed");
+ exit(bx::kExitFailure);
+ }
+
+ *indices++ = (uint16_t)vertexIndex;
++numIndices;
}
}
@@ -1032,64 +1053,27 @@ int main(int _argc, const char* _argv[])
);
}
- if (0 < primitives.size() )
- {
- if (hasTangent)
- {
- calcTangents(vertexData, uint16_t(numVertices), decl, indexData, numIndices);
- }
-
- bx::MemoryWriter memWriter(&memBlock);
-
- triReorderElapsed -= bx::getHPCounter();
- for (PrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
- {
- const Primitive& prim1 = *primIt;
- triangleReorder(indexData + prim1.m_startIndex, prim1.m_numIndices, numVertices, 32);
- if (compress)
- {
- triangleCompress(&memWriter
- , indexData + prim1.m_startIndex
- , prim1.m_numIndices
- , vertexData + prim1.m_startVertex
- , numVertices
- , uint16_t(stride)
- );
- }
- }
- triReorderElapsed += bx::getHPCounter();
-
- write(&writer
- , vertexData
- , numVertices
- , decl
- , indexData
- , numIndices
- , (uint8_t*)memBlock.more()
- , memBlock.getSize()
- , material
- , primitives
- );
- }
+ BX_CHECK(0 == primitives.size(), "Not all primitives are written");
- printf("size: %d\n", uint32_t(bx::seek(&writer) ) );
+ bx::printf("size: %d\n", uint32_t(bx::seek(&writer) ) );
bx::close(&writer);
+ delete [] table;
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"
+ bx::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
+ , writtenPrimitives
+ , writtenVertices
+ , writtenIndices
);
return bx::kExitSuccess;