Changeset 239 for trunk/src/formats/obj_loader.cc
- Timestamp:
- 05/17/14 02:35:19 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/formats/obj_loader.cc
r238 r239 56 56 bool read_stream( std::istream& stream ); 57 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; }58 virtual size_t raw_size() const = 0; 59 virtual const uint8* raw_pointer() const = 0; 60 60 virtual void calculate_tangents() {} 61 61 … … 151 151 152 152 153 struct mesh_obj_reader : public obj_reader154 {155 mesh_obj_reader( mesh_data_creator* m ) : m_mesh( m ) {}156 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count );157 virtual void calculate_tangents();158 159 mesh_data_creator* m_mesh;160 };161 162 size_t mesh_obj_reader::add_face( uint32* vi, uint32* ti, uint32* ni, size_t count )163 {164 if ( count < 3 )165 {166 // TODO : report error?167 return 0;168 }169 170 // TODO : support if normals not present;171 172 std::vector< vec3 >& vp = m_mesh->get_positions();173 std::vector< vec3 >& vn = m_mesh->get_normals();174 std::vector< vec2 >& vt = m_mesh->get_texcoords();175 176 std::size_t result = 0;177 178 // Simple triangulation - obj's shouldn't have more than quads anyway179 for ( size_t i = 2; i < count; ++i )180 {181 result++;182 vp.push_back( v[ vi[ 0 ] ] ); vt.push_back( t[ ti[ 0 ] ] ); vn.push_back( n[ ni[ 0 ] ] );183 vp.push_back( v[ vi[ i-1 ] ] ); vt.push_back( t[ ti[ i-1 ] ] ); vn.push_back( n[ ni[ i-1 ] ] );184 vp.push_back( v[ vi[ i ] ] ); vt.push_back( t[ ti[ i ] ] ); vn.push_back( n[ ni[ i ] ] );185 }186 187 return result;188 }189 190 // based on http://www.terathon.com/code/tangent.html191 void mesh_obj_reader::calculate_tangents()192 {193 const std::vector< vec3 >& vp = m_mesh->get_positions();194 const std::vector< vec2 >& vt = m_mesh->get_texcoords();195 const std::vector< vec3 >& vn = m_mesh->get_normals();196 std::vector< vec3 >& tg = m_mesh->get_tangents();197 198 size_t count = vp.size();199 size_t tcount = count / 3;200 201 std::vector< vec3 > tan1( count );202 std::vector< vec3 > tan2( count );203 tg.resize( count );204 205 for (size_t a = 0; a < tcount; ++a )206 {207 size_t i1 = a * 3;208 size_t i2 = a * 3 + 1;209 size_t i3 = a * 3 + 2;210 211 // TODO: simplify212 213 const vec3& v1 = vp[i1];214 const vec3& v2 = vp[i2];215 const vec3& v3 = vp[i3];216 217 const vec2& w1 = vt[i1];218 const vec2& w2 = vt[i2];219 const vec2& w3 = vt[i3];220 221 vec3 xyz1 = v2 - v1;222 vec3 xyz2 = v3 - v1;223 //vec2 st1 = w2 - w1;224 //vec2 st2 = w3 - w1;225 226 float s1 = w2.x - w1.x;227 float t1 = w2.y - w1.y;228 float s2 = w3.x - w1.x;229 float t2 = w3.y - w1.y;230 231 float stst = s1 * t2 - s2 * t1;232 float r = 0.0f;233 if (stst > 0.0f || stst < 0.0f) r = 1.0f / stst;234 235 vec3 sdir = ( t2 * xyz1 - t1 * xyz2 ) * r;236 vec3 tdir = ( s1 * xyz2 - s2 * xyz1 ) * r;237 238 // the += below obviously doesn't make sense in this case, but I'll239 // leave it here for when I move to indices240 tan1[i1] += sdir;241 tan1[i2] += sdir;242 tan1[i3] += sdir;243 244 // tan2 not needed anymore??245 tan2[i1] += tdir;246 tan2[i2] += tdir;247 tan2[i3] += tdir;248 }249 250 for (std::size_t a = 0; a < count; ++a )251 {252 const vec3& n = vn[a];253 const vec3& t = tan1[a];254 if ( ! (t.x == 0.0f && t.y == 0.0f && t.z == 0.0f) )255 tg[a] = vec3( glm::normalize(t - n * glm::dot( n, t )) );256 //tg[a][3] = (glm::dot(glm::cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;257 }258 259 }260 261 nv::obj_loader::obj_loader( bool tangents )262 : m_mesh( nullptr ), m_tangents( tangents )263 {264 265 }266 267 nv::obj_loader::~obj_loader()268 {269 delete m_mesh;270 }271 272 bool nv::obj_loader::load( stream& source )273 {274 if ( m_mesh != nullptr ) delete m_mesh;275 mesh_data_creator creator;276 mesh_obj_reader reader( &creator );277 std_stream sstream( &source );278 reader.read_stream( sstream );279 m_size = reader.size;280 if ( m_tangents )281 {282 reader.calculate_tangents();283 }284 m_mesh = creator.release();285 return true;286 }287 153 288 154 struct mesh_data_reader_vt : public obj_reader … … 305 171 } 306 172 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(); }173 virtual size_t raw_size() const { return m_data.size() * sizeof( obj_vertex_vt ); } 174 virtual const uint8* raw_pointer() const { return (const uint8*)m_data.data(); } 309 175 }; 310 176 … … 328 194 } 329 195 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(); }196 virtual size_t raw_size() const { return m_data.size() * sizeof( obj_vertex_vtn ); } 197 virtual const uint8* raw_pointer() const { return (const uint8*)m_data.data(); } 332 198 }; 333 199 … … 351 217 } 352 218 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(); }219 virtual size_t raw_size() const { return m_data.size() * sizeof( obj_vertex_vtnt ); } 220 virtual const uint8* raw_pointer() const { return (const uint8*)m_data.data(); } 355 221 356 222 // based on http://www.terathon.com/code/tangent.html … … 423 289 }; 424 290 425 nv:: wavefront_loader::wavefront_loader( bool normals /*= true*/, bool tangents /*= false */ )291 nv::obj_loader::obj_loader( bool normals /*= true*/, bool tangents /*= false */ ) 426 292 : m_normals( normals ), m_tangents( tangents ), m_mesh( nullptr ) 427 293 { … … 437 303 } 438 304 439 bool nv:: wavefront_loader::load( stream& source )305 bool nv::obj_loader::load( stream& source ) 440 306 { 441 307 if ( m_mesh ) delete m_mesh; … … 462 328 mesh_raw_channel* channel = new mesh_raw_channel(); 463 329 nv::uint8* data = nullptr; 330 464 331 if ( reader->raw_size() > 0 ) 465 332 { … … 479 346 } 480 347 481 mesh_data* nv:: wavefront_loader::release_mesh_data()348 mesh_data* nv::obj_loader::release_mesh_data() 482 349 { 483 350 mesh_data* result = m_mesh; … … 486 353 } 487 354 488 nv:: wavefront_loader::~wavefront_loader()355 nv::obj_loader::~obj_loader() 489 356 { 490 357 if ( m_mesh ) delete m_mesh;
Note: See TracChangeset
for help on using the changeset viewer.