Ignore:
Timestamp:
05/21/14 17:40:06 (11 years ago)
Author:
epyon
Message:
  • multiple mesh per file interface for all mesh loaders added
  • multiple mesh per file obj and md5 loader support added
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/formats/obj_loader.cc

    r239 r240  
    1616        vec2 texcoord;
    1717
    18         obj_vertex_vt( vec3 a_position, vec2 a_texcoord )
     18        obj_vertex_vt( vec3 a_position, vec2 a_texcoord, vec3 )
    1919                : position( a_position ), texcoord( a_texcoord ) {}
    2020};
     
    5252
    5353        std::size_t size;
     54        bool        eof;
    5455
    5556        obj_reader();
     
    5758        virtual size_t add_face( uint32* vi, uint32* ti, uint32* ni, size_t count ) = 0;
    5859        virtual size_t raw_size() const = 0;
     60        virtual void reset() = 0;
    5961        virtual const uint8* raw_pointer() const = 0;
    6062        virtual void calculate_tangents() {}
     
    7072        t.push_back( vec2() );
    7173        size = 0;
     74        eof = false;
    7275}
    7376
    7477bool obj_reader::read_stream( std::istream& stream )
    7578{
     79        bool added_faces = false;
    7680        f32 x, y, z;
     81        if ( eof ) return false;
    7782
    7883        while ( std::getline( stream, line ) )
     
    109114                if ( cmd == "f" )
    110115                {
     116                        added_faces = true;
    111117                        ss >> cmd;
    112118
     
    138144                }
    139145
    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                {
    143154                        continue;
    144155                }
     
    147158        }
    148159
     160        eof = true;
    149161        return true;
    150162}
    151163
    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 )
     164template < typename VTX >
     165struct 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 )
    158169        {
    159170                if ( count < 3 ) return 0; // TODO : report error?
     171
    160172                // TODO : support if normals not present;
     173                vec3 nullvec;
    161174                std::size_t result = 0;
    162175                // 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                        }
    169196                }
    170197                return result;
    171198        }
    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 ); }
    174203        virtual const uint8* raw_pointer() const { return (const uint8*)m_data.data(); }
    175204};
    176205
    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
     207struct mesh_data_reader_vt : public mesh_data_reader< obj_vertex_vt >
     208{
     209        mesh_data_reader_vt() : mesh_data_reader( false ) {}
     210};
     211
     212struct mesh_data_reader_vtn : public mesh_data_reader< obj_vertex_vtn >
     213{
     214        mesh_data_reader_vtn() : mesh_data_reader( true ) {}
     215};
     216
     217struct mesh_data_reader_vtnt : public mesh_data_reader< obj_vertex_vtnt >
     218{
     219        mesh_data_reader_vtnt() : mesh_data_reader( true ) {}
    221220
    222221        // based on http://www.terathon.com/code/tangent.html
     
    290289
    291290nv::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 )
    293292{
    294293        if ( normals )
     
    305304bool nv::obj_loader::load( stream& source )
    306305{
    307         if ( m_mesh ) delete m_mesh;
    308        
    309306        obj_reader* reader = nullptr;
    310307        if ( m_normals )
     
    318315                reader = new mesh_data_reader_vt();
    319316        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                }
    326324       
    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        }
    340344        delete reader;
    341 
    342         m_mesh = new mesh_data();
    343         m_mesh->add_channel( channel );
    344345        return true;
    345346
    346347}
    347348
    348 mesh_data* nv::obj_loader::release_mesh_data()
    349 {
    350         mesh_data* result = m_mesh;
    351         m_mesh = nullptr;
     349mesh_data* nv::obj_loader::release_mesh_data( size_t index )
     350{
     351        mesh_data* result = m_meshes[ index ];
     352        m_meshes[ index ] = nullptr;
    352353        return result;
    353354}
     
    355356nv::obj_loader::~obj_loader()
    356357{
    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.