@@ -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
278289static 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
0 commit comments