Changeset 240 for trunk/src/formats/obj_loader.cc
- Timestamp:
- 05/21/14 17:40:06 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/formats/obj_loader.cc
r239 r240 16 16 vec2 texcoord; 17 17 18 obj_vertex_vt( vec3 a_position, vec2 a_texcoord )18 obj_vertex_vt( vec3 a_position, vec2 a_texcoord, vec3 ) 19 19 : position( a_position ), texcoord( a_texcoord ) {} 20 20 }; … … 52 52 53 53 std::size_t size; 54 bool eof; 54 55 55 56 obj_reader(); … … 57 58 virtual size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) = 0; 58 59 virtual size_t raw_size() const = 0; 60 virtual void reset() = 0; 59 61 virtual const uint8* raw_pointer() const = 0; 60 62 virtual void calculate_tangents() {} … … 70 72 t.push_back( vec2() ); 71 73 size = 0; 74 eof = false; 72 75 } 73 76 74 77 bool obj_reader::read_stream( std::istream& stream ) 75 78 { 79 bool added_faces = false; 76 80 f32 x, y, z; 81 if ( eof ) return false; 77 82 78 83 while ( std::getline( stream, line ) ) … … 109 114 if ( cmd == "f" ) 110 115 { 116 added_faces = true; 111 117 ss >> cmd; 112 118 … … 138 144 } 139 145 140 if ( cmd == "g" || cmd == "s" ) 141 { 142 // ignored 146 if ( cmd == "g" ) 147 { 148 if (added_faces) return true; 149 continue; 150 } 151 152 if ( cmd == "s" ) 153 { 143 154 continue; 144 155 } … … 147 158 } 148 159 160 eof = true; 149 161 return true; 150 162 } 151 163 152 153 154 struct mesh_data_reader_vt : public obj_reader 155 { 156 mesh_data_reader_vt() {} 157 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32*, size_t count ) 164 template < typename VTX > 165 struct mesh_data_reader : public obj_reader 166 { 167 mesh_data_reader( bool normals ) : m_normals( normals ) {} 168 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) 158 169 { 159 170 if ( count < 3 ) return 0; // TODO : report error? 171 160 172 // TODO : support if normals not present; 173 vec3 nullvec; 161 174 std::size_t result = 0; 162 175 // Simple triangulation - obj's shouldn't have more than quads anyway 163 for ( size_t i = 2; i < count; ++i ) 164 { 165 result++; 166 m_data.emplace_back( v[ vi[ 0 ] ], t[ ti[ 0 ] ] ); 167 m_data.emplace_back( v[ vi[ i-1 ] ], t[ ti[ i-1 ] ] ); 168 m_data.emplace_back( v[ vi[ i ] ], t[ ti[ i ] ] ); 176 177 if ( m_normals ) 178 { 179 for ( size_t i = 2; i < count; ++i ) 180 { 181 result++; 182 m_data.emplace_back( v[ vi[ 0 ] ], t[ ti[ 0 ] ], n[ ni[ 0 ] ] ); 183 m_data.emplace_back( v[ vi[ i-1 ] ], t[ ti[ i-1 ] ], n[ ni[ i-1 ] ] ); 184 m_data.emplace_back( v[ vi[ i ] ], t[ ti[ i ] ], n[ ni[ i ] ] ); 185 } 186 } 187 else 188 { 189 for ( size_t i = 2; i < count; ++i ) 190 { 191 result++; 192 m_data.emplace_back( v[ vi[ 0 ] ], t[ ti[ 0 ] ], nullvec ); 193 m_data.emplace_back( v[ vi[ i-1 ] ], t[ ti[ i-1 ] ], nullvec ); 194 m_data.emplace_back( v[ vi[ i ] ], t[ ti[ i ] ], nullvec ); 195 } 169 196 } 170 197 return result; 171 198 } 172 std::vector< obj_vertex_vt > m_data; 173 virtual size_t raw_size() const { return m_data.size() * sizeof( obj_vertex_vt ); } 199 bool m_normals; 200 std::vector< VTX > m_data; 201 virtual void reset() { m_data.clear(); } 202 virtual size_t raw_size() const { return m_data.size() * sizeof( VTX ); } 174 203 virtual const uint8* raw_pointer() const { return (const uint8*)m_data.data(); } 175 204 }; 176 205 177 struct mesh_data_reader_vtn : public obj_reader 178 { 179 mesh_data_reader_vtn() {} 180 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) 181 { 182 if ( count < 3 ) return 0; // TODO : report error? 183 // TODO : support if normals not present; 184 std::size_t result = 0; 185 // Simple triangulation - obj's shouldn't have more than quads anyway 186 for ( size_t i = 2; i < count; ++i ) 187 { 188 result++; 189 m_data.emplace_back( v[ vi[ 0 ] ], t[ ti[ 0 ] ], n[ ni[ 0 ] ] ); 190 m_data.emplace_back( v[ vi[ i-1 ] ], t[ ti[ i-1 ] ], n[ ni[ i-1 ] ] ); 191 m_data.emplace_back( v[ vi[ i ] ], t[ ti[ i ] ], n[ ni[ i ] ] ); 192 } 193 return result; 194 } 195 std::vector< obj_vertex_vtn > m_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(); } 198 }; 199 200 struct mesh_data_reader_vtnt : public obj_reader 201 { 202 mesh_data_reader_vtnt() {} 203 virtual std::size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) 204 { 205 if ( count < 3 ) return 0; // TODO : report error? 206 // TODO : support if normals not present; 207 std::size_t result = 0; 208 // Simple triangulation - obj's shouldn't have more than quads anyway 209 for ( size_t i = 2; i < count; ++i ) 210 { 211 result++; 212 m_data.emplace_back( v[ vi[ 0 ] ], t[ ti[ 0 ] ], n[ ni[ 0 ] ] ); 213 m_data.emplace_back( v[ vi[ i-1 ] ], t[ ti[ i-1 ] ], n[ ni[ i-1 ] ] ); 214 m_data.emplace_back( v[ vi[ i ] ], t[ ti[ i ] ], n[ ni[ i ] ] ); 215 } 216 return result; 217 } 218 std::vector< obj_vertex_vtnt > m_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(); } 206 207 struct mesh_data_reader_vt : public mesh_data_reader< obj_vertex_vt > 208 { 209 mesh_data_reader_vt() : mesh_data_reader( false ) {} 210 }; 211 212 struct mesh_data_reader_vtn : public mesh_data_reader< obj_vertex_vtn > 213 { 214 mesh_data_reader_vtn() : mesh_data_reader( true ) {} 215 }; 216 217 struct mesh_data_reader_vtnt : public mesh_data_reader< obj_vertex_vtnt > 218 { 219 mesh_data_reader_vtnt() : mesh_data_reader( true ) {} 221 220 222 221 // based on http://www.terathon.com/code/tangent.html … … 290 289 291 290 nv::obj_loader::obj_loader( bool normals /*= true*/, bool tangents /*= false */ ) 292 : m_normals( normals ), m_tangents( tangents ) , m_mesh( nullptr )291 : m_normals( normals ), m_tangents( tangents ) 293 292 { 294 293 if ( normals ) … … 305 304 bool nv::obj_loader::load( stream& source ) 306 305 { 307 if ( m_mesh ) delete m_mesh;308 309 306 obj_reader* reader = nullptr; 310 307 if ( m_normals ) … … 318 315 reader = new mesh_data_reader_vt(); 319 316 std_stream sstream( &source ); 320 reader->read_stream( sstream ); 321 322 if ( m_tangents ) 323 { 324 reader->calculate_tangents(); 325 } 317 318 while ( reader->read_stream( sstream ) ) 319 { 320 if ( m_tangents ) 321 { 322 reader->calculate_tangents(); 323 } 326 324 327 328 mesh_raw_channel* channel = new mesh_raw_channel(); 329 nv::uint8* data = nullptr; 330 331 if ( reader->raw_size() > 0 ) 332 { 333 data = new uint8[ reader->raw_size() ]; 334 std::copy_n( reader->raw_pointer(), reader->raw_size(), data ); 335 } 336 channel->data = data; 337 channel->desc = m_descriptor; 338 channel->count = reader->size * 3; 339 channel->size = reader->raw_size(); 325 mesh_raw_channel* channel = new mesh_raw_channel(); 326 nv::uint8* data = nullptr; 327 328 if ( reader->raw_size() > 0 ) 329 { 330 data = new uint8[ reader->raw_size() ]; 331 std::copy_n( reader->raw_pointer(), reader->raw_size(), data ); 332 } 333 channel->data = data; 334 channel->desc = m_descriptor; 335 channel->count = reader->size * 3; 336 channel->size = reader->raw_size(); 337 338 mesh_data* mesh = new mesh_data(); 339 mesh->add_channel( channel ); 340 m_meshes.push_back( mesh ); 341 342 reader->reset(); 343 } 340 344 delete reader; 341 342 m_mesh = new mesh_data();343 m_mesh->add_channel( channel );344 345 return true; 345 346 346 347 } 347 348 348 mesh_data* nv::obj_loader::release_mesh_data( )349 { 350 mesh_data* result = m_mesh ;351 m_mesh = nullptr;349 mesh_data* nv::obj_loader::release_mesh_data( size_t index ) 350 { 351 mesh_data* result = m_meshes[ index ]; 352 m_meshes[ index ] = nullptr; 352 353 return result; 353 354 } … … 355 356 nv::obj_loader::~obj_loader() 356 357 { 357 if ( m_mesh ) delete m_mesh;358 } 358 for ( auto mesh : m_meshes ) if ( mesh ) delete mesh; 359 }
Note: See TracChangeset
for help on using the changeset viewer.