Skip to content

Commit eaf8623

Browse files
committed
Fix build of viewer example.
Bump version.
1 parent dcad3e6 commit eaf8623

File tree

5 files changed

+182
-101
lines changed

5 files changed

+182
-101
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,14 @@ TinyObjLoader is successfully used in ...
9898
* PBR material extension for .MTL. Its proposed here: http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr
9999
* Callback API for custom loading.
100100
* Double precision support(for HPC application).
101+
* Smoothing group
101102

102103

103104
## TODO
104105

105106
* [ ] Fix obj_sticker example.
106107
* [ ] More unit test codes.
107108
* [x] Texture options
108-
* [ ] Normal vector generation
109-
* [ ] Support smoothing groups
110109

111110
## License
112111

examples/viewer/viewer.cc

Lines changed: 120 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -190,90 +190,101 @@ static void CalcNormal(float N[3], float v0[3], float v1[3], float v2[3]) {
190190
float len = sqrtf(len2);
191191

192192
N[0] /= len;
193-
N[1] /= len;
194-
N[2] /= len;
193+
N[1] /= len;
194+
N[2] /= len;
195195
}
196196
}
197197

198-
namespace // Local utility functions
198+
namespace // Local utility functions
199199
{
200-
void addBtoA(float a[3], float b[3])
201-
{
202-
for (size_t i = 0; i < 3; ++i)
203-
a[i] += b[i];
204-
}
205-
206-
void assignBtoA(float a[3], float b[3])
207-
{
208-
for (size_t i = 0; i < 3; ++i)
209-
a[i] = b[i];
210-
}
211-
212-
void normalizeVector(float N[3])
213-
{
214-
float len2 = N[0] * N[0] + N[1] * N[1] + N[2] * N[2];
215-
if (len2 > 0.0f) {
216-
float len = sqrtf(len2);
217-
218-
N[0] /= len;
219-
N[1] /= len;
220-
N[2] /= len;
221-
}
222-
}
223-
224-
void computeSmoothingNormals(tinyobj::attrib_t &attrib, tinyobj::shape_t &shape,
225-
std::map<int, float[3]>& smoothVertexNormals)
226-
{
227-
smoothVertexNormals.clear();
228-
std::map<int, float[3]>::iterator iter;
229-
230-
for (size_t f = 0; f < shape.mesh.indices.size() / 3; f++) {
231-
// Get the three indexes of the face (all faces are triangular)
232-
tinyobj::index_t idx0 = shape.mesh.indices[3 * f + 0];
233-
tinyobj::index_t idx1 = shape.mesh.indices[3 * f + 1];
234-
tinyobj::index_t idx2 = shape.mesh.indices[3 * f + 2];
235-
236-
// Get the three vertex indexes and coordinates
237-
int vi[3]; // indexes
238-
float v[3][3]; // coordinates
239-
240-
for (int k = 0; k < 3; k++) {
241-
vi[0] = idx0.vertex_index;
242-
vi[1] = idx1.vertex_index;
243-
vi[2] = idx2.vertex_index;
244-
assert(vi[0] >= 0);
245-
assert(vi[1] >= 0);
246-
assert(vi[2] >= 0);
247-
248-
v[0][k] = attrib.vertices[3 * vi[0] + k];
249-
v[1][k] = attrib.vertices[3 * vi[1] + k];
250-
v[2][k] = attrib.vertices[3 * vi[2] + k];
251-
}
252-
253-
// Compute the normal of the face
254-
float normal[3];
255-
CalcNormal(normal, v[0], v[1], v[2]);
256-
257-
// Add the normal to the three vertexes
258-
for (size_t i = 0; i < 3; ++i)
259-
{
260-
iter = smoothVertexNormals.find(vi[i]);
261-
if (iter != smoothVertexNormals.end())
262-
addBtoA(iter->second, normal);
263-
else
264-
assignBtoA(smoothVertexNormals[vi[i]], normal);
265-
}
266-
267-
} // f
268-
269-
// Normalize the normals, that is, make them unit vectors
270-
for (iter = smoothVertexNormals.begin(); iter != smoothVertexNormals.end(); iter++)
271-
{
272-
normalizeVector(iter->second);
273-
}
274-
275-
} // computeSmoothingNormals
276-
} // namespace
200+
struct vec3 {
201+
float v[3];
202+
vec3() {
203+
v[0] = 0.0f;
204+
v[1] = 0.0f;
205+
v[2] = 0.0f;
206+
}
207+
};
208+
209+
void normalizeVector(vec3 &v) {
210+
float len2 = v.v[0] * v.v[0] + v.v[1] * v.v[1] + v.v[2] * v.v[2];
211+
if (len2 > 0.0f) {
212+
float len = sqrtf(len2);
213+
214+
v.v[0] /= len;
215+
v.v[1] /= len;
216+
v.v[2] /= len;
217+
}
218+
}
219+
220+
// Check if `mesh_t` contains smoothing group id.
221+
bool hasSmoothingGroup(const tinyobj::shape_t& shape)
222+
{
223+
for (size_t i = 0; i < shape.mesh.smoothing_group_ids.size(); i++) {
224+
if (shape.mesh.smoothing_group_ids[i] > 0) {
225+
return true;
226+
}
227+
}
228+
return false;
229+
}
230+
231+
void computeSmoothingNormals(const tinyobj::attrib_t& attrib, const tinyobj::shape_t& shape,
232+
std::map<int, vec3>& smoothVertexNormals) {
233+
smoothVertexNormals.clear();
234+
std::map<int, vec3>::iterator iter;
235+
236+
for (size_t f = 0; f < shape.mesh.indices.size() / 3; f++) {
237+
// Get the three indexes of the face (all faces are triangular)
238+
tinyobj::index_t idx0 = shape.mesh.indices[3 * f + 0];
239+
tinyobj::index_t idx1 = shape.mesh.indices[3 * f + 1];
240+
tinyobj::index_t idx2 = shape.mesh.indices[3 * f + 2];
241+
242+
// Get the three vertex indexes and coordinates
243+
int vi[3]; // indexes
244+
float v[3][3]; // coordinates
245+
246+
for (int k = 0; k < 3; k++) {
247+
vi[0] = idx0.vertex_index;
248+
vi[1] = idx1.vertex_index;
249+
vi[2] = idx2.vertex_index;
250+
assert(vi[0] >= 0);
251+
assert(vi[1] >= 0);
252+
assert(vi[2] >= 0);
253+
254+
v[0][k] = attrib.vertices[3 * vi[0] + k];
255+
v[1][k] = attrib.vertices[3 * vi[1] + k];
256+
v[2][k] = attrib.vertices[3 * vi[2] + k];
257+
}
258+
259+
// Compute the normal of the face
260+
float normal[3];
261+
CalcNormal(normal, v[0], v[1], v[2]);
262+
263+
// Add the normal to the three vertexes
264+
for (size_t i = 0; i < 3; ++i) {
265+
iter = smoothVertexNormals.find(vi[i]);
266+
if (iter != smoothVertexNormals.end()) {
267+
// add
268+
iter->second.v[0] += normal[0];
269+
iter->second.v[1] += normal[1];
270+
iter->second.v[2] += normal[2];
271+
} else {
272+
smoothVertexNormals[vi[i]].v[0] = normal[0];
273+
smoothVertexNormals[vi[i]].v[1] = normal[1];
274+
smoothVertexNormals[vi[i]].v[2] = normal[2];
275+
}
276+
}
277+
278+
} // f
279+
280+
// Normalize the normals, that is, make them unit vectors
281+
for (iter = smoothVertexNormals.begin(); iter != smoothVertexNormals.end();
282+
iter++) {
283+
normalizeVector(iter->second);
284+
}
285+
286+
} // computeSmoothingNormals
287+
} // namespace
277288

278289
static bool LoadObjAndConvert(float bmin[3], float bmax[3],
279290
std::vector<DrawObject>* drawObjects,
@@ -389,12 +400,14 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
389400
DrawObject o;
390401
std::vector<float> buffer; // pos(3float), normal(3float), color(3float)
391402

392-
// Check for smoothing group and compute smoothing normals
393-
std::map<int, float[3]> smoothVertexNormals;
394-
if (shapes[s].smoothingGroupId > 0)
395-
computeSmoothingNormals(attrib, shapes[s], smoothVertexNormals);
403+
// Check for smoothing group and compute smoothing normals
404+
std::map<int, vec3> smoothVertexNormals;
405+
if (hasSmoothingGroup(shapes[s]) > 0) {
406+
std::cout << "Compute smoothingNormal for shape [" << s << "]" << std::endl;
407+
computeSmoothingNormals(attrib, shapes[s], smoothVertexNormals);
408+
}
396409

397-
for (size_t f = 0; f < shapes[s].mesh.indices.size() / 3; f++) {
410+
for (size_t f = 0; f < shapes[s].mesh.indices.size() / 3; f++) {
398411
tinyobj::index_t idx0 = shapes[s].mesh.indices[3 * f + 0];
399412
tinyobj::index_t idx1 = shapes[s].mesh.indices[3 * f + 1];
400413
tinyobj::index_t idx2 = shapes[s].mesh.indices[3 * f + 2];
@@ -498,19 +511,28 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
498511
invalid_normal_index = true;
499512
}
500513

501-
if (invalid_normal_index && !smoothVertexNormals.empty()) {
502-
// Use smoothing normals
503-
int f0 = idx0.vertex_index;
504-
int f1 = idx1.vertex_index;
505-
int f2 = idx2.vertex_index;
506-
507-
if (f0 >= 0 && f1 >= 0 && f2 >= 0) {
508-
assignBtoA(n[0], smoothVertexNormals[f0]);
509-
assignBtoA(n[1], smoothVertexNormals[f1]);
510-
assignBtoA(n[2], smoothVertexNormals[f2]);
511-
invalid_normal_index = false;
512-
}
513-
}
514+
if (invalid_normal_index && !smoothVertexNormals.empty()) {
515+
// Use smoothing normals
516+
int f0 = idx0.vertex_index;
517+
int f1 = idx1.vertex_index;
518+
int f2 = idx2.vertex_index;
519+
520+
if (f0 >= 0 && f1 >= 0 && f2 >= 0) {
521+
n[0][0] = smoothVertexNormals[f0].v[0];
522+
n[0][1] = smoothVertexNormals[f0].v[1];
523+
n[0][2] = smoothVertexNormals[f0].v[2];
524+
525+
n[1][0] = smoothVertexNormals[f1].v[0];
526+
n[1][1] = smoothVertexNormals[f1].v[1];
527+
n[1][2] = smoothVertexNormals[f1].v[2];
528+
529+
n[2][0] = smoothVertexNormals[f2].v[0];
530+
n[2][1] = smoothVertexNormals[f2].v[1];
531+
n[2][2] = smoothVertexNormals[f2].v[2];
532+
533+
invalid_normal_index = false;
534+
}
535+
}
514536

515537
if (invalid_normal_index) {
516538
// compute geometric normal

models/smoothing-normal.mtl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
newmtl white
2+
Ka 0 0 0
3+
Kd 1 1 1
4+
Ks 0 0 0
5+
6+
newmtl red
7+
Ka 0 0 0
8+
Kd 1 0 0
9+
Ks 0 0 0
10+
11+
newmtl green
12+
Ka 0 0 0
13+
Kd 0 1 0
14+
Ks 0 0 0
15+
16+
newmtl blue
17+
Ka 0 0 0
18+
Kd 0 0 1
19+
Ks 0 0 0
20+
21+
newmtl light
22+
Ka 20 20 20
23+
Kd 1 1 1
24+
Ks 0 0 0

models/smoothing-normal.obj

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
mtllib smoothing-normal.mtl
2+
3+
v 0.000000 2.000000 2.000000
4+
v 0.000000 0.000000 2.000000
5+
v 2.000000 0.000000 2.000000
6+
v 2.000000 2.000000 2.000000
7+
v 0.000000 2.000000 0.000000
8+
v 0.000000 0.000000 0.000000
9+
v 2.000000 0.000000 0.000000
10+
v 2.000000 2.000000 0.000000
11+
# 8 vertices
12+
13+
g front cube
14+
usemtl white
15+
s 1
16+
f 1 2 3 4
17+
#g bottom cube
18+
#usemtl white
19+
s 1
20+
f 2 6 7 3
21+
22+
g back cube
23+
# expects white material
24+
s off
25+
f 8 7 6 5
26+
#g right cube
27+
#usemtl red
28+
#f 4 3 7 8
29+
#g top cube
30+
#usemtl white
31+
#f 5 1 4 8
32+
#g left cube
33+
#usemtl green
34+
#f 5 6 2 1
35+
# 6 elements

tiny_obj_loader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
The MIT License (MIT)
33
4-
Copyright (c) 2012-2017 Syoyo Fujita and many contributors.
4+
Copyright (c) 2012-2018 Syoyo Fujita and many contributors.
55
66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@ THE SOFTWARE.
2323
*/
2424

2525
//
26+
// version 1.1.1 : Support smoothing groups(#162)
2627
// version 1.1.0 : Support parsing vertex color(#144)
2728
// version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138)
2829
// version 1.0.7 : Support multiple tex options(#126)

0 commit comments

Comments
 (0)