Optimzie face generation.

This commit is contained in:
Syoyo Fujita
2016-05-24 12:58:31 +09:00
parent 8c03771aac
commit 8880438c36

View File

@@ -623,7 +623,7 @@ struct CommandCount
} }
}; };
static bool parseLine(Command *command, const char *p, size_t p_len) static bool parseLine(Command *command, const char *p, size_t p_len, bool triangulate = true)
{ {
char linebuf[4096]; char linebuf[4096];
assert(p_len < 4095); assert(p_len < 4095);
@@ -690,6 +690,8 @@ static bool parseLine(Command *command, const char *p, size_t p_len)
//token += strspn(token, " \t"); //token += strspn(token, " \t");
skip_space(&token); skip_space(&token);
StackVector<vertex_index, 8> f;
while (!IS_NEW_LINE(token[0])) { while (!IS_NEW_LINE(token[0])) {
vertex_index vi = parseRawTriple(&token); vertex_index vi = parseRawTriple(&token);
//printf("v = %d, %d, %d\n", vi.v_idx, vi.vn_idx, vi.vt_idx); //printf("v = %d, %d, %d\n", vi.v_idx, vi.vn_idx, vi.vt_idx);
@@ -700,11 +702,31 @@ static bool parseLine(Command *command, const char *p, size_t p_len)
//token += n; //token += n;
skip_space_and_cr(&token); skip_space_and_cr(&token);
command->f.push_back(vi); f->push_back(vi);
} }
command->type = COMMAND_F; command->type = COMMAND_F;
if (triangulate) {
vertex_index i0 = f[0];
vertex_index i1(-1);
vertex_index i2 = f[1];
for (size_t k = 2; k < f->size(); k++) {
i1 = i2;
i2 = f[k];
command->f.emplace_back(i0);
command->f.emplace_back(i1);
command->f.emplace_back(i2);
}
} else {
for (size_t k = 0; k < f->size(); k++) {
command->f.emplace_back(f[k]);
}
}
return true; return true;
} }
@@ -965,8 +987,8 @@ bool parse(std::vector<float, lt::allocator<float>> &vertices, std::vector<float
} }
//std::cout << "# of lines = " << line_sum << std::endl; //std::cout << "# of lines = " << line_sum << std::endl;
//std::vector<Command> commands[kMaxThreads]; std::vector<Command> commands[kMaxThreads];
std::vector<Command, lt::allocator<Command> > commands[kMaxThreads]; //thread_local std::vector<Command, lt::allocator<Command> > commands;
// 2. allocate buffer // 2. allocate buffer
auto t_alloc_start = std::chrono::high_resolution_clock::now(); auto t_alloc_start = std::chrono::high_resolution_clock::now();
@@ -1001,7 +1023,7 @@ bool parse(std::vector<float, lt::allocator<float>> &vertices, std::vector<float
} else if (command.type == COMMAND_VT) { } else if (command.type == COMMAND_VT) {
command_count[t].num_vt++; command_count[t].num_vt++;
} else if (command.type == COMMAND_F) { } else if (command.type == COMMAND_F) {
command_count[t].num_f++; command_count[t].num_f += command.f.size();
} }
commands[t].emplace_back(std::move(command)); commands[t].emplace_back(std::move(command));
} }
@@ -1046,31 +1068,39 @@ bool parse(std::vector<float, lt::allocator<float>> &vertices, std::vector<float
{ {
auto t_start = std::chrono::high_resolution_clock::now(); auto t_start = std::chrono::high_resolution_clock::now();
vertices.reserve(num_v * 3); vertices.resize(num_v * 3);
normals.reserve(num_vn * 3); normals.resize(num_vn * 3);
texcoords.reserve(num_vt * 2); texcoords.resize(num_vt * 2);
faces.reserve(num_f); faces.resize(num_f);
size_t v_count = 0;
size_t n_count = 0;
size_t t_count = 0;
size_t f_count = 0;
for (size_t t = 0; t < num_threads; t++) { for (size_t t = 0; t < num_threads; t++) {
for (size_t i = 0; i < commands[t].size(); i++) { for (size_t i = 0; i < commands[t].size(); i++) {
if (commands[t][i].type == COMMAND_EMPTY) { if (commands[t][i].type == COMMAND_EMPTY) {
continue; continue;
} else if (commands[t][i].type == COMMAND_V) { } else if (commands[t][i].type == COMMAND_V) {
vertices.emplace_back(commands[t][i].vx); vertices[3*v_count+0] = commands[t][i].vx;
vertices.emplace_back(commands[t][i].vy); vertices[3*v_count+1] = commands[t][i].vy;
vertices.emplace_back(commands[t][i].vz); vertices[3*v_count+2] = commands[t][i].vz;
v_count++;
} else if (commands[t][i].type == COMMAND_VN) { } else if (commands[t][i].type == COMMAND_VN) {
normals.emplace_back(commands[t][i].nx); normals[3*n_count+0] = commands[t][i].nx;
normals.emplace_back(commands[t][i].ny); normals[3*n_count+1] = commands[t][i].ny;
normals.emplace_back(commands[t][i].nz); normals[3*n_count+2] = commands[t][i].nz;
n_count++;
} else if (commands[t][i].type == COMMAND_VT) { } else if (commands[t][i].type == COMMAND_VT) {
texcoords.emplace_back(commands[t][i].tx); texcoords[2*t_count+0] = commands[t][i].tx;
texcoords.emplace_back(commands[t][i].ty); texcoords[2*t_count+1] = commands[t][i].ty;
t_count++;
} else if (commands[t][i].type == COMMAND_F) { } else if (commands[t][i].type == COMMAND_F) {
int v_size = vertices.size() / 3; int v_size = vertices.size() / 3;
int vn_size = normals.size() / 3; int vn_size = normals.size() / 3;
int vt_size = texcoords.size() / 2; int vt_size = texcoords.size() / 2;
#if 0
// triangulate. // triangulate.
{ {
vertex_index i0 = commands[t][i].f[0]; vertex_index i0 = commands[t][i].f[0];
@@ -1094,6 +1124,17 @@ bool parse(std::vector<float, lt::allocator<float>> &vertices, std::vector<float
faces.emplace_back(std::move(vertex_index(v_idx, vt_idx, vn_idx))); faces.emplace_back(std::move(vertex_index(v_idx, vt_idx, vn_idx)));
} }
} }
#else
for (size_t k = 0; k < commands[t][i].f.size(); k++) {
vertex_index &vi = commands[t][i].f[k];
int v_idx = fixIndex(vi.v_idx, v_size);
int vn_idx = fixIndex(vi.vn_idx, vn_size);
int vt_idx = fixIndex(vi.vt_idx, vt_size);
faces[f_count + k] = vertex_index(v_idx, vn_idx, vt_idx);
}
f_count += commands[t][i].f.size();
#endif
} }
} }
} }