- Timestamp:
- 05/16/14 05:48:01 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/formats/obj_loader.cc
r225 r238 11 11 using namespace nv; 12 12 13 struct obj_vertex_vt 14 { 15 vec3 position; 16 vec2 texcoord; 17 18 obj_vertex_vt( vec3 a_position, vec2 a_texcoord ) 19 : position( a_position ), texcoord( a_texcoord ) {} 20 }; 21 22 struct obj_vertex_vtn 23 { 24 vec3 position; 25 vec2 texcoord; 26 vec3 normal; 27 28 obj_vertex_vtn( vec3 a_position, vec2 a_texcoord, vec3 a_normal ) 29 : position( a_position ), texcoord( a_texcoord ), normal( a_normal ) {} 30 }; 31 32 33 struct obj_vertex_vtnt 34 { 35 vec3 position; 36 vec2 texcoord; 37 vec3 normal; 38 vec4 tangent; 39 40 obj_vertex_vtnt( vec3 a_position, vec2 a_texcoord, vec3 a_normal ) 41 : position( a_position ), texcoord( a_texcoord ), normal( a_normal ) {} 42 }; 43 13 44 struct obj_reader 14 45 { … … 24 55 obj_reader(); 25 56 bool read_stream( std::istream& stream ); 26 27 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) = 0; 57 virtual size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) = 0; 58 virtual size_t raw_size() { return 0; } 59 virtual const uint8* raw_pointer() { return nullptr; } 60 virtual void calculate_tangents() {} 61 28 62 virtual ~obj_reader(){} 29 63 }; … … 120 154 { 121 155 mesh_obj_reader( mesh_data_creator* m ) : m_mesh( m ) {} 122 virtual std::size_t add_face( uint32* v , uint32* t, uint32* n, size_t count );156 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ); 123 157 virtual void calculate_tangents(); 124 158 … … 238 272 bool nv::obj_loader::load( stream& source ) 239 273 { 240 if ( m_mesh != nullptr ) 241 { 242 delete m_mesh; 243 } 274 if ( m_mesh != nullptr ) delete m_mesh; 244 275 mesh_data_creator creator; 245 276 mesh_obj_reader reader( &creator ); … … 254 285 return true; 255 286 } 287 288 struct mesh_data_reader_vt : public obj_reader 289 { 290 mesh_data_reader_vt() {} 291 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32*, size_t count ) 292 { 293 if ( count < 3 ) return 0; // TODO : report error? 294 // TODO : support if normals not present; 295 std::size_t result = 0; 296 // Simple triangulation - obj's shouldn't have more than quads anyway 297 for ( size_t i = 2; i < count; ++i ) 298 { 299 result++; 300 m_data.emplace_back( v[ vi[ 0 ] ], t[ ti[ 0 ] ] ); 301 m_data.emplace_back( v[ vi[ i-1 ] ], t[ ti[ i-1 ] ] ); 302 m_data.emplace_back( v[ vi[ i ] ], t[ ti[ i ] ] ); 303 } 304 return result; 305 } 306 std::vector< obj_vertex_vt > m_data; 307 virtual size_t raw_size() { return m_data.size() * sizeof( obj_vertex_vt ); } 308 virtual const uint8* raw_pointer() { return (const uint8*)m_data.data(); } 309 }; 310 311 struct mesh_data_reader_vtn : public obj_reader 312 { 313 mesh_data_reader_vtn() {} 314 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) 315 { 316 if ( count < 3 ) return 0; // TODO : report error? 317 // TODO : support if normals not present; 318 std::size_t result = 0; 319 // Simple triangulation - obj's shouldn't have more than quads anyway 320 for ( size_t i = 2; i < count; ++i ) 321 { 322 result++; 323 m_data.emplace_back( v[ vi[ 0 ] ], t[ ti[ 0 ] ], n[ ni[ 0 ] ] ); 324 m_data.emplace_back( v[ vi[ i-1 ] ], t[ ti[ i-1 ] ], n[ ni[ i-1 ] ] ); 325 m_data.emplace_back( v[ vi[ i ] ], t[ ti[ i ] ], n[ ni[ i ] ] ); 326 } 327 return result; 328 } 329 std::vector< obj_vertex_vtn > m_data; 330 virtual size_t raw_size() { return m_data.size() * sizeof( obj_vertex_vtn ); } 331 virtual const uint8* raw_pointer() { return (const uint8*)m_data.data(); } 332 }; 333 334 struct mesh_data_reader_vtnt : public obj_reader 335 { 336 mesh_data_reader_vtnt() {} 337 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) 338 { 339 if ( count < 3 ) return 0; // TODO : report error? 340 // TODO : support if normals not present; 341 std::size_t result = 0; 342 // Simple triangulation - obj's shouldn't have more than quads anyway 343 for ( size_t i = 2; i < count; ++i ) 344 { 345 result++; 346 m_data.emplace_back( v[ vi[ 0 ] ], t[ ti[ 0 ] ], n[ ni[ 0 ] ] ); 347 m_data.emplace_back( v[ vi[ i-1 ] ], t[ ti[ i-1 ] ], n[ ni[ i-1 ] ] ); 348 m_data.emplace_back( v[ vi[ i ] ], t[ ti[ i ] ], n[ ni[ i ] ] ); 349 } 350 return result; 351 } 352 std::vector< obj_vertex_vtnt > m_data; 353 virtual size_t raw_size() { return m_data.size() * sizeof( obj_vertex_vtnt ); } 354 virtual const uint8* raw_pointer() { return (const uint8*)m_data.data(); } 355 356 // based on http://www.terathon.com/code/tangent.html 357 void calculate_tangents() 358 { 359 // const std::vector< vec3 >& vp = m_mesh->get_positions(); 360 // const std::vector< vec2 >& vt = m_mesh->get_texcoords(); 361 // const std::vector< vec3 >& vn = m_mesh->get_normals(); 362 // std::vector< vec3 >& tg = m_mesh->get_tangents(); 363 364 size_t count = m_data.size(); 365 size_t tcount = count / 3; 366 367 std::vector< vec3 > tan1( count ); 368 std::vector< vec3 > tan2( count ); 369 370 for (size_t a = 0; a < tcount; ++a ) 371 { 372 size_t i1 = a * 3; 373 size_t i2 = a * 3 + 1; 374 size_t i3 = a * 3 + 2; 375 obj_vertex_vtnt& vtx1 = m_data[ i1 ]; 376 obj_vertex_vtnt& vtx2 = m_data[ i2 ]; 377 obj_vertex_vtnt& vtx3 = m_data[ i3 ]; 378 379 // TODO: simplify 380 vec3 xyz1 = vtx2.position - vtx1.position; 381 vec3 xyz2 = vtx3.position - vtx1.position; 382 //vec2 st1 = w2 - w1; 383 //vec2 st2 = w3 - w1; 384 385 float s1 = vtx2.texcoord.x - vtx1.texcoord.x; 386 float t1 = vtx2.texcoord.y - vtx1.texcoord.y; 387 float s2 = vtx3.texcoord.x - vtx1.texcoord.x; 388 float t2 = vtx3.texcoord.y - vtx1.texcoord.y; 389 390 float stst = s1 * t2 - s2 * t1; 391 float r = 0.0f; 392 if (stst > 0.0f || stst < 0.0f) r = 1.0f / stst; 393 394 vec3 sdir = ( t2 * xyz1 - t1 * xyz2 ) * r; 395 vec3 tdir = ( s1 * xyz2 - s2 * xyz1 ) * r; 396 397 // the += below obviously doesn't make sense in this case, but I'll 398 // leave it here for when I move to indices 399 tan1[i1] += sdir; 400 tan1[i2] += sdir; 401 tan1[i3] += sdir; 402 403 // tan2 not needed anymore?? 404 tan2[i1] += tdir; 405 tan2[i2] += tdir; 406 tan2[i3] += tdir; 407 } 408 409 for (std::size_t a = 0; a < count; ++a ) 410 { 411 const vec3& n = m_data[a].normal; 412 const vec3& t = tan1[a]; 413 if ( ! (t.x == 0.0f && t.y == 0.0f && t.z == 0.0f) ) 414 { 415 m_data[a].tangent = vec4( glm::normalize(t - n * glm::dot( n, t )), 0.0f ); 416 m_data[a].tangent[3] = (glm::dot(glm::cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f; 417 } 418 } 419 420 } 421 422 423 }; 424 425 nv::wavefront_loader::wavefront_loader( bool normals /*= true*/, bool tangents /*= false */ ) 426 : m_normals( normals ), m_tangents( tangents ), m_mesh( nullptr ) 427 { 428 if ( normals ) 429 { 430 if ( tangents ) 431 m_descriptor.initialize<obj_vertex_vtnt>(); 432 else 433 m_descriptor.initialize<obj_vertex_vtn>(); 434 } 435 else 436 m_descriptor.initialize<obj_vertex_vt>(); 437 } 438 439 bool nv::wavefront_loader::load( stream& source ) 440 { 441 if ( m_mesh ) delete m_mesh; 442 443 obj_reader* reader = nullptr; 444 if ( m_normals ) 445 { 446 if ( m_tangents ) 447 reader = new mesh_data_reader_vtnt(); 448 else 449 reader = new mesh_data_reader_vtn(); 450 } 451 else 452 reader = new mesh_data_reader_vt(); 453 std_stream sstream( &source ); 454 reader->read_stream( sstream ); 455 456 if ( m_tangents ) 457 { 458 reader->calculate_tangents(); 459 } 460 461 462 mesh_raw_channel* channel = new mesh_raw_channel(); 463 nv::uint8* data = nullptr; 464 if ( reader->raw_size() > 0 ) 465 { 466 data = new uint8[ reader->raw_size() ]; 467 std::copy_n( reader->raw_pointer(), reader->raw_size(), data ); 468 } 469 channel->data = data; 470 channel->desc = m_descriptor; 471 channel->count = reader->size * 3; 472 channel->size = reader->raw_size(); 473 delete reader; 474 475 m_mesh = new mesh_data(); 476 m_mesh->add_channel( channel ); 477 return true; 478 479 } 480 481 mesh_data* nv::wavefront_loader::release_mesh_data() 482 { 483 mesh_data* result = m_mesh; 484 m_mesh = nullptr; 485 return result; 486 } 487 488 nv::wavefront_loader::~wavefront_loader() 489 { 490 if ( m_mesh ) delete m_mesh; 491 }
Note: See TracChangeset
for help on using the changeset viewer.