Skip to content

Commit

Permalink
gltfpack: Don't include redundant normal/texcoord streams from .obj
Browse files Browse the repository at this point in the history
When parsing .obj files, we don't have a specific indication that meshes
include normal/UV data. In fact, it's possible for some faces in the
mesh to have normals and others to not have normals.

This change implements simple filtering that only saves normal/texcoord
streams if at least one vertex in the mesh has the data specified.

This doesn't have a large impact on size when compression is used, but
it's more correct.
  • Loading branch information
zeux committed Jan 27, 2020
1 parent 8cae357 commit caf10d4
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions tools/gltfpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,9 @@ void parseMeshesObj(fastObjMesh* obj, cgltf_data* data, std::vector<Mesh>& meshe
mesh.targets = 0;
}

std::vector<char> mesh_normals(meshes.size());
std::vector<char> mesh_texcoords(meshes.size());

std::vector<size_t> vertex_offset(material_count);
std::vector<size_t> index_offset(material_count);

Expand All @@ -581,6 +584,9 @@ void parseMeshesObj(fastObjMesh* obj, cgltf_data* data, std::vector<Mesh>& meshe
mesh.streams[0].data[vo + vi] = p;
mesh.streams[1].data[vo + vi] = n;
mesh.streams[2].data[vo + vi] = t;

mesh_normals[mesh_index[mi]] |= ii.n > 0;
mesh_texcoords[mesh_index[mi]] |= ii.t > 0;
}

for (unsigned int vi = 2; vi < obj->face_vertices[fi]; ++vi)
Expand All @@ -596,6 +602,21 @@ void parseMeshesObj(fastObjMesh* obj, cgltf_data* data, std::vector<Mesh>& meshe
index_offset[mi] += (obj->face_vertices[fi] - 2) * 3;
group_offset += obj->face_vertices[fi];
}

for (size_t i = 0; i < meshes.size(); ++i)
{
Mesh& mesh = meshes[i];

assert(mesh.streams.size() == 3);
assert(mesh.streams[1].type == cgltf_attribute_type_normal);
assert(mesh.streams[2].type == cgltf_attribute_type_texcoord);

if (!mesh_texcoords[i])
mesh.streams.erase(mesh.streams.begin() + 2);

if (!mesh_normals[i])
mesh.streams.erase(mesh.streams.begin() + 1);
}
}

void parseAnimations(cgltf_data* data, std::vector<Animation>& animations)
Expand Down

0 comments on commit caf10d4

Please sign in to comment.