Fix build of viewer example.

Bump version.
This commit is contained in:
Syoyo Fujita
2018-02-04 14:05:36 +09:00
parent dcad3e6c50
commit eaf8623e61
5 changed files with 168 additions and 87 deletions

View File

@@ -98,6 +98,7 @@ TinyObjLoader is successfully used in ...
* PBR material extension for .MTL. Its proposed here: http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr * PBR material extension for .MTL. Its proposed here: http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr
* Callback API for custom loading. * Callback API for custom loading.
* Double precision support(for HPC application). * Double precision support(for HPC application).
* Smoothing group
## TODO ## TODO
@@ -105,8 +106,6 @@ TinyObjLoader is successfully used in ...
* [ ] Fix obj_sticker example. * [ ] Fix obj_sticker example.
* [ ] More unit test codes. * [ ] More unit test codes.
* [x] Texture options * [x] Texture options
* [ ] Normal vector generation
* [ ] Support smoothing groups
## License ## License

View File

@@ -190,90 +190,101 @@ static void CalcNormal(float N[3], float v0[3], float v1[3], float v2[3]) {
float len = sqrtf(len2); float len = sqrtf(len2);
N[0] /= len; N[0] /= len;
N[1] /= len; N[1] /= len;
N[2] /= len; N[2] /= len;
} }
} }
namespace // Local utility functions namespace // Local utility functions
{ {
void addBtoA(float a[3], float b[3]) struct vec3 {
{ float v[3];
for (size_t i = 0; i < 3; ++i) vec3() {
a[i] += b[i]; v[0] = 0.0f;
} v[1] = 0.0f;
v[2] = 0.0f;
}
};
void assignBtoA(float a[3], float b[3]) void normalizeVector(vec3 &v) {
{ float len2 = v.v[0] * v.v[0] + v.v[1] * v.v[1] + v.v[2] * v.v[2];
for (size_t i = 0; i < 3; ++i) if (len2 > 0.0f) {
a[i] = b[i]; float len = sqrtf(len2);
}
void normalizeVector(float N[3]) v.v[0] /= len;
{ v.v[1] /= len;
float len2 = N[0] * N[0] + N[1] * N[1] + N[2] * N[2]; v.v[2] /= len;
if (len2 > 0.0f) { }
float len = sqrtf(len2); }
N[0] /= len; // Check if `mesh_t` contains smoothing group id.
N[1] /= len; bool hasSmoothingGroup(const tinyobj::shape_t& shape)
N[2] /= len; {
} for (size_t i = 0; i < shape.mesh.smoothing_group_ids.size(); i++) {
} if (shape.mesh.smoothing_group_ids[i] > 0) {
return true;
}
}
return false;
}
void computeSmoothingNormals(tinyobj::attrib_t &attrib, tinyobj::shape_t &shape, void computeSmoothingNormals(const tinyobj::attrib_t& attrib, const tinyobj::shape_t& shape,
std::map<int, float[3]>& smoothVertexNormals) std::map<int, vec3>& smoothVertexNormals) {
{ smoothVertexNormals.clear();
smoothVertexNormals.clear(); std::map<int, vec3>::iterator iter;
std::map<int, float[3]>::iterator iter;
for (size_t f = 0; f < shape.mesh.indices.size() / 3; f++) { for (size_t f = 0; f < shape.mesh.indices.size() / 3; f++) {
// Get the three indexes of the face (all faces are triangular) // Get the three indexes of the face (all faces are triangular)
tinyobj::index_t idx0 = shape.mesh.indices[3 * f + 0]; tinyobj::index_t idx0 = shape.mesh.indices[3 * f + 0];
tinyobj::index_t idx1 = shape.mesh.indices[3 * f + 1]; tinyobj::index_t idx1 = shape.mesh.indices[3 * f + 1];
tinyobj::index_t idx2 = shape.mesh.indices[3 * f + 2]; tinyobj::index_t idx2 = shape.mesh.indices[3 * f + 2];
// Get the three vertex indexes and coordinates // Get the three vertex indexes and coordinates
int vi[3]; // indexes int vi[3]; // indexes
float v[3][3]; // coordinates float v[3][3]; // coordinates
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
vi[0] = idx0.vertex_index; vi[0] = idx0.vertex_index;
vi[1] = idx1.vertex_index; vi[1] = idx1.vertex_index;
vi[2] = idx2.vertex_index; vi[2] = idx2.vertex_index;
assert(vi[0] >= 0); assert(vi[0] >= 0);
assert(vi[1] >= 0); assert(vi[1] >= 0);
assert(vi[2] >= 0); assert(vi[2] >= 0);
v[0][k] = attrib.vertices[3 * vi[0] + k]; v[0][k] = attrib.vertices[3 * vi[0] + k];
v[1][k] = attrib.vertices[3 * vi[1] + k]; v[1][k] = attrib.vertices[3 * vi[1] + k];
v[2][k] = attrib.vertices[3 * vi[2] + k]; v[2][k] = attrib.vertices[3 * vi[2] + k];
} }
// Compute the normal of the face // Compute the normal of the face
float normal[3]; float normal[3];
CalcNormal(normal, v[0], v[1], v[2]); CalcNormal(normal, v[0], v[1], v[2]);
// Add the normal to the three vertexes // Add the normal to the three vertexes
for (size_t i = 0; i < 3; ++i) for (size_t i = 0; i < 3; ++i) {
{ iter = smoothVertexNormals.find(vi[i]);
iter = smoothVertexNormals.find(vi[i]); if (iter != smoothVertexNormals.end()) {
if (iter != smoothVertexNormals.end()) // add
addBtoA(iter->second, normal); iter->second.v[0] += normal[0];
else iter->second.v[1] += normal[1];
assignBtoA(smoothVertexNormals[vi[i]], normal); iter->second.v[2] += normal[2];
} } else {
smoothVertexNormals[vi[i]].v[0] = normal[0];
smoothVertexNormals[vi[i]].v[1] = normal[1];
smoothVertexNormals[vi[i]].v[2] = normal[2];
}
}
} // f } // f
// Normalize the normals, that is, make them unit vectors // Normalize the normals, that is, make them unit vectors
for (iter = smoothVertexNormals.begin(); iter != smoothVertexNormals.end(); iter++) for (iter = smoothVertexNormals.begin(); iter != smoothVertexNormals.end();
{ iter++) {
normalizeVector(iter->second); normalizeVector(iter->second);
} }
} // computeSmoothingNormals } // computeSmoothingNormals
} // namespace } // namespace
static bool LoadObjAndConvert(float bmin[3], float bmax[3], static bool LoadObjAndConvert(float bmin[3], float bmax[3],
std::vector<DrawObject>* drawObjects, std::vector<DrawObject>* drawObjects,
@@ -389,12 +400,14 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
DrawObject o; DrawObject o;
std::vector<float> buffer; // pos(3float), normal(3float), color(3float) std::vector<float> buffer; // pos(3float), normal(3float), color(3float)
// Check for smoothing group and compute smoothing normals // Check for smoothing group and compute smoothing normals
std::map<int, float[3]> smoothVertexNormals; std::map<int, vec3> smoothVertexNormals;
if (shapes[s].smoothingGroupId > 0) if (hasSmoothingGroup(shapes[s]) > 0) {
computeSmoothingNormals(attrib, shapes[s], smoothVertexNormals); std::cout << "Compute smoothingNormal for shape [" << s << "]" << std::endl;
computeSmoothingNormals(attrib, shapes[s], smoothVertexNormals);
}
for (size_t f = 0; f < shapes[s].mesh.indices.size() / 3; f++) { for (size_t f = 0; f < shapes[s].mesh.indices.size() / 3; f++) {
tinyobj::index_t idx0 = shapes[s].mesh.indices[3 * f + 0]; tinyobj::index_t idx0 = shapes[s].mesh.indices[3 * f + 0];
tinyobj::index_t idx1 = shapes[s].mesh.indices[3 * f + 1]; tinyobj::index_t idx1 = shapes[s].mesh.indices[3 * f + 1];
tinyobj::index_t idx2 = shapes[s].mesh.indices[3 * f + 2]; tinyobj::index_t idx2 = shapes[s].mesh.indices[3 * f + 2];
@@ -498,19 +511,28 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
invalid_normal_index = true; invalid_normal_index = true;
} }
if (invalid_normal_index && !smoothVertexNormals.empty()) { if (invalid_normal_index && !smoothVertexNormals.empty()) {
// Use smoothing normals // Use smoothing normals
int f0 = idx0.vertex_index; int f0 = idx0.vertex_index;
int f1 = idx1.vertex_index; int f1 = idx1.vertex_index;
int f2 = idx2.vertex_index; int f2 = idx2.vertex_index;
if (f0 >= 0 && f1 >= 0 && f2 >= 0) { if (f0 >= 0 && f1 >= 0 && f2 >= 0) {
assignBtoA(n[0], smoothVertexNormals[f0]); n[0][0] = smoothVertexNormals[f0].v[0];
assignBtoA(n[1], smoothVertexNormals[f1]); n[0][1] = smoothVertexNormals[f0].v[1];
assignBtoA(n[2], smoothVertexNormals[f2]); n[0][2] = smoothVertexNormals[f0].v[2];
invalid_normal_index = false;
} n[1][0] = smoothVertexNormals[f1].v[0];
} n[1][1] = smoothVertexNormals[f1].v[1];
n[1][2] = smoothVertexNormals[f1].v[2];
n[2][0] = smoothVertexNormals[f2].v[0];
n[2][1] = smoothVertexNormals[f2].v[1];
n[2][2] = smoothVertexNormals[f2].v[2];
invalid_normal_index = false;
}
}
if (invalid_normal_index) { if (invalid_normal_index) {
// compute geometric normal // compute geometric normal

View File

@@ -0,0 +1,24 @@
newmtl white
Ka 0 0 0
Kd 1 1 1
Ks 0 0 0
newmtl red
Ka 0 0 0
Kd 1 0 0
Ks 0 0 0
newmtl green
Ka 0 0 0
Kd 0 1 0
Ks 0 0 0
newmtl blue
Ka 0 0 0
Kd 0 0 1
Ks 0 0 0
newmtl light
Ka 20 20 20
Kd 1 1 1
Ks 0 0 0

View File

@@ -0,0 +1,35 @@
mtllib smoothing-normal.mtl
v 0.000000 2.000000 2.000000
v 0.000000 0.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 2.000000 2.000000
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
# 8 vertices
g front cube
usemtl white
s 1
f 1 2 3 4
#g bottom cube
#usemtl white
s 1
f 2 6 7 3
g back cube
# expects white material
s off
f 8 7 6 5
#g right cube
#usemtl red
#f 4 3 7 8
#g top cube
#usemtl white
#f 5 1 4 8
#g left cube
#usemtl green
#f 5 6 2 1
# 6 elements

View File

@@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2012-2017 Syoyo Fujita and many contributors. Copyright (c) 2012-2018 Syoyo Fujita and many contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@ THE SOFTWARE.
*/ */
// //
// version 1.1.1 : Support smoothing groups(#162)
// version 1.1.0 : Support parsing vertex color(#144) // version 1.1.0 : Support parsing vertex color(#144)
// version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138) // version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138)
// version 1.0.7 : Support multiple tex options(#126) // version 1.0.7 : Support multiple tex options(#126)