Ignore:
Timestamp:
05/17/14 02:35:19 (11 years ago)
Author:
epyon
Message:
  • massive update of mesh handling
  • universal mesh handling routines
  • removed a lot of legacy code
  • significantly streamlined MD5 loading
  • all tests updated to new features
File:
1 edited

Legend:

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

    r238 r239  
    5656        bool read_stream( std::istream& stream );
    5757        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;
    6060        virtual void calculate_tangents() {}
    6161
     
    151151
    152152
    153 struct mesh_obj_reader : public obj_reader
    154 {
    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 anyway
    179         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.html
    191 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: simplify
    212 
    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'll
    239                 // leave it here for when I move to indices
    240                 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 }
    287153
    288154struct mesh_data_reader_vt : public obj_reader
     
    305171        }
    306172        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(); }
    309175};
    310176
     
    328194        }
    329195        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(); }
    332198};
    333199
     
    351217        }
    352218        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(); }
    355221
    356222        // based on http://www.terathon.com/code/tangent.html
     
    423289};
    424290
    425 nv::wavefront_loader::wavefront_loader( bool normals /*= true*/, bool tangents /*= false */ )
     291nv::obj_loader::obj_loader( bool normals /*= true*/, bool tangents /*= false */ )
    426292        : m_normals( normals ), m_tangents( tangents ), m_mesh( nullptr )
    427293{
     
    437303}
    438304
    439 bool nv::wavefront_loader::load( stream& source )
     305bool nv::obj_loader::load( stream& source )
    440306{
    441307        if ( m_mesh ) delete m_mesh;
     
    462328        mesh_raw_channel* channel = new mesh_raw_channel();
    463329        nv::uint8* data = nullptr;
     330
    464331        if ( reader->raw_size() > 0 )
    465332        {
     
    479346}
    480347
    481 mesh_data* nv::wavefront_loader::release_mesh_data()
     348mesh_data* nv::obj_loader::release_mesh_data()
    482349{
    483350        mesh_data* result = m_mesh;
     
    486353}
    487354
    488 nv::wavefront_loader::~wavefront_loader()
     355nv::obj_loader::~obj_loader()
    489356{
    490357        if ( m_mesh ) delete m_mesh;
Note: See TracChangeset for help on using the changeset viewer.