Skip to content

Commit 0d4a133

Browse files
authored
Merge pull request zeux#890 from zeux/gltf-lines
gltfpack: Implement support for lines in OBJ files
2 parents baa0dd0 + affc5f4 commit 0d4a133

2 files changed

Lines changed: 57 additions & 12 deletions

File tree

extern/fast_obj.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ typedef struct
137137
unsigned int face_count;
138138
unsigned int* face_vertices;
139139
unsigned int* face_materials;
140+
unsigned char* face_lines;
140141

141142
/* Index data: one element for each face vertex */
142143
unsigned int index_count;
@@ -734,7 +735,7 @@ const char* parse_normal(fastObjData* data, const char* ptr)
734735

735736

736737
static
737-
const char* parse_face(fastObjData* data, const char* ptr)
738+
const char* parse_face(fastObjData* data, const char* ptr, unsigned char line)
738739
{
739740
unsigned int count;
740741
fastObjIndex vn;
@@ -796,6 +797,16 @@ const char* parse_face(fastObjData* data, const char* ptr)
796797
array_push(data->mesh->face_vertices, count);
797798
array_push(data->mesh->face_materials, data->material);
798799

800+
if (line || data->mesh->face_lines)
801+
{
802+
/* when line info exists, ensure it uses aligned indexing with other face data */
803+
size_t skipped = array_size(data->mesh->face_vertices) - array_size(data->mesh->face_lines);
804+
while (--skipped > 0)
805+
array_push(data->mesh->face_lines, 0);
806+
807+
array_push(data->mesh->face_lines, line);
808+
}
809+
799810
data->group.face_count++;
800811
data->object.face_count++;
801812

@@ -1295,7 +1306,22 @@ void parse_buffer(fastObjData* data, const char* ptr, const char* end, const fas
12951306
{
12961307
case ' ':
12971308
case '\t':
1298-
p = parse_face(data, p);
1309+
p = parse_face(data, p, 0);
1310+
break;
1311+
1312+
default:
1313+
p--; /* roll p++ back in case *p was a newline */
1314+
}
1315+
break;
1316+
1317+
case 'l':
1318+
p++;
1319+
1320+
switch (*p++)
1321+
{
1322+
case ' ':
1323+
case '\t':
1324+
p = parse_face(data, p, 1);
12991325
break;
13001326

13011327
default:
@@ -1398,6 +1424,7 @@ void fast_obj_destroy(fastObjMesh* m)
13981424
array_clean(m->colors);
13991425
array_clean(m->face_vertices);
14001426
array_clean(m->face_materials);
1427+
array_clean(m->face_lines);
14011428
array_clean(m->indices);
14021429
array_clean(m->objects);
14031430
array_clean(m->groups);
@@ -1454,6 +1481,7 @@ fastObjMesh* fast_obj_read_with_callbacks(const char* path, const fastObjCallbac
14541481
m->colors = 0;
14551482
m->face_vertices = 0;
14561483
m->face_materials = 0;
1484+
m->face_lines = 0;
14571485
m->indices = 0;
14581486
m->materials = 0;
14591487
m->textures = 0;

gltf/parseobj.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,33 @@ static void parseMeshObj(fastObjMesh* obj, unsigned int face_offset, unsigned in
216216
{
217217
unsigned int face_vertices = obj->face_vertices[face_offset + fi];
218218

219-
for (unsigned int vi = 2; vi < face_vertices; ++vi)
219+
if (mesh.type == cgltf_primitive_type_lines)
220220
{
221-
size_t to = index_offset + (vi - 2) * 3;
221+
for (unsigned int vi = 1; vi < face_vertices; ++vi)
222+
{
223+
size_t to = index_offset + (vi - 1) * 2;
222224

223-
mesh.indices[to + 0] = remap[vertex_offset];
224-
mesh.indices[to + 1] = remap[vertex_offset + vi - 1];
225-
mesh.indices[to + 2] = remap[vertex_offset + vi];
225+
mesh.indices[to + 0] = remap[vertex_offset + vi - 1];
226+
mesh.indices[to + 1] = remap[vertex_offset + vi];
227+
}
228+
229+
vertex_offset += face_vertices;
230+
index_offset += (face_vertices - 1) * 2;
226231
}
232+
else
233+
{
234+
for (unsigned int vi = 2; vi < face_vertices; ++vi)
235+
{
236+
size_t to = index_offset + (vi - 2) * 3;
227237

228-
vertex_offset += face_vertices;
229-
index_offset += (face_vertices - 2) * 3;
238+
mesh.indices[to + 0] = remap[vertex_offset];
239+
mesh.indices[to + 1] = remap[vertex_offset + vi - 1];
240+
mesh.indices[to + 2] = remap[vertex_offset + vi];
241+
}
242+
243+
vertex_offset += face_vertices;
244+
index_offset += (face_vertices - 2) * 3;
245+
}
230246
}
231247

232248
assert(vertex_offset == face_vertex_count);
@@ -241,16 +257,17 @@ static void parseMeshGroupObj(fastObjMesh* obj, const fastObjGroup& og, cgltf_da
241257
for (unsigned int face_offset = og.face_offset; face_offset < face_end_offset;)
242258
{
243259
unsigned int mi = obj->face_materials[face_offset];
260+
unsigned char isl = obj->face_lines ? obj->face_lines[face_offset] : 0;
244261

245262
unsigned int face_count = 0;
246263
unsigned int face_vertex_count = 0;
247264
unsigned int index_count = 0;
248265

249-
for (unsigned int fj = face_offset; fj < face_end_offset && obj->face_materials[fj] == mi; ++fj)
266+
for (unsigned int fj = face_offset; fj < face_end_offset && obj->face_materials[fj] == mi && (!obj->face_lines || obj->face_lines[fj] == isl); ++fj)
250267
{
251268
face_count += 1;
252269
face_vertex_count += obj->face_vertices[fj];
253-
index_count += (obj->face_vertices[fj] - 2) * 3;
270+
index_count += isl ? (obj->face_vertices[fj] - 1) * 2 : (obj->face_vertices[fj] - 2) * 3;
254271
}
255272

256273
meshes.push_back(Mesh());
@@ -262,7 +279,7 @@ static void parseMeshGroupObj(fastObjMesh* obj, const fastObjGroup& og, cgltf_da
262279
mesh.material = &data->materials[mi];
263280
}
264281

265-
mesh.type = cgltf_primitive_type_triangles;
282+
mesh.type = isl ? cgltf_primitive_type_lines : cgltf_primitive_type_triangles;
266283
mesh.targets = 0;
267284

268285
if (node)

0 commit comments

Comments
 (0)