Ignore:
Timestamp:
01/26/16 18:59:46 (9 years ago)
Author:
epyon
Message:
  • massive update (need to start doing atomics again) :/
File:
1 edited

Legend:

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

    r482 r485  
    1212
    1313using namespace nv;
     14
     15namespace nv {
     16
     17        struct assimp_data
     18        {
     19                const aiScene* scene;
     20                vector< const aiBone* > bones;
     21                vector< const aiNode* > nodes;
     22                vector< const aiMesh* > meshes;
     23                vector< const aiNode* > skeletons;
     24
     25                hash_store< shash64, const aiBone* > bone_by_name;
     26                hash_store< shash64, const aiNode* > node_by_name;
     27        };
     28
     29}
    1430
    1531const unsigned MAX_BONES = 64;
     
    5874
    5975nv::assimp_loader::assimp_loader( string_table* strings, const string_view& a_ext, uint32 a_assimp_flags /*= 0 */ )
    60         : mesh_loader( strings ), m_scene( nullptr ), m_mesh_count(0)
     76        : mesh_loader( strings ), m_mesh_count(0)
    6177{
    6278        m_ext   = a_ext;
     
    7692                        aiProcess_SortByPType                   | 
    7793                        aiProcess_FindDegenerates               | 
    78                         aiProcess_FindInvalidData               | 
     94                        aiProcess_FindDegenerates |
    7995                        0 );
    8096        }
     97        m_data = new assimp_data;
     98        m_data->scene = nullptr;
    8199}
    82100
     
    85103{
    86104        load_assimp_library();
    87         if ( m_scene != nullptr ) aiReleaseImport( reinterpret_cast<const aiScene*>( m_scene ) );
    88         m_scene = nullptr;
     105        if ( m_data->scene != nullptr ) aiReleaseImport( m_data->scene );
     106        m_data->scene = nullptr;
    89107        m_mesh_count = 0;
    90108        NV_LOG_NOTICE( "AssImp loading file..." );
     
    99117                return false;
    100118        }
    101         m_scene      = scene;
    102         m_mesh_count = scene->mNumMeshes;
     119        m_data->scene = scene;
     120        m_mesh_count  = scene->mNumMeshes;
    103121        NV_LOG_NOTICE( "Loading successfull" );
     122
     123        scan_nodes( scene->mRootNode );
     124
     125        for ( unsigned i = 0; i < scene->mRootNode->mNumChildren; ++i )
     126        {
     127                const aiNode* node = scene->mRootNode->mChildren[i];
     128                if ( node->mNumMeshes == 0 )
     129                        m_data->skeletons.push_back( node );
     130        }
     131
     132        for ( nv::uint32 i = 0; i < m_mesh_count; i++ )
     133        {
     134                data_node_info info;
     135                data_channel_set* data = data_channel_set_creator::create_set( 2 );
     136                load_mesh_data( data, i, info );
     137                m_meshes.push_back( data );
     138                m_mesh_info.push_back( info );
     139        }
     140
     141        scene_report();
    104142        return true;
    105143}
     
    108146{
    109147        if ( index >= m_mesh_count ) return nullptr;
    110         data_channel_set* result = data_channel_set_creator::create_set( 2 );
    111         load_mesh_data( result, index, info );
    112         return result;
     148        info = m_mesh_info[index];
     149        return m_meshes[index];
    113150}
    114151void nv::assimp_loader::load_mesh_data( data_channel_set* data, size_t index, data_node_info& info )
    115152{
    116         const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
    117         const aiMesh*  mesh  = scene->mMeshes[ index ];
     153        const aiMesh*  mesh  = m_data->scene->mMeshes[ index ];
    118154
    119155        bool skinned = mesh->mNumBones > 0;
     
    125161                desc.initialize< assimp_plain_vtx >();
    126162        data_channel_set_creator maccess( data );
    127         const char* name = mesh->mName.data;
     163        string64 name( mesh->mName.data, mesh->mName.length );
     164        if ( mesh->mName.length == 0 )
     165        {
     166                for ( auto node : m_data->nodes )
     167                {
     168                        if ( node->mMeshes )
     169                                for ( uint32 i = 0; i < node->mNumMeshes; ++i )
     170                                        if ( node->mMeshes[i] == index )
     171                                        {
     172                                                name.assign( node->mName.data, node->mName.length );
     173                                                if ( i != 0 )
     174                                                {
     175                                                        name.append( "#0" );
     176                                                        name.append( i );
     177                                                }
     178                                        }
     179
     180                }
     181        }
    128182        info.name = make_name( name );
    129183        info.parent_id = -1;
     184        int hack_for_node_anim;
     185        if ( is_node_animated() )
     186                info.parent_id = index;
     187
     188
    130189        uint8*  cdata   = maccess.add_channel( desc, mesh->mNumVertices ).raw_data();
    131190        uint16* indices = reinterpret_cast<uint16*>( maccess.add_channel< index_u16 >( mesh->mNumFaces * 3 ).raw_data() );
     
    188247nv::assimp_loader::~assimp_loader()
    189248{
    190         if ( m_scene != nullptr ) aiReleaseImport( reinterpret_cast<const aiScene*>( m_scene ) );
    191 }
    192 
    193 bool nv::assimp_loader::load_bones( size_t index, array_ref< data_node_info > bones )
    194 {
    195         if ( m_scene == nullptr ) return false;
    196         const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
    197         const aiMesh*  mesh  = scene->mMeshes[ index ];
    198 
    199         for (unsigned int m=0; m<mesh->mNumBones; m++)
    200         {
    201                 aiBone* bone   = mesh->mBones[m];
    202                 mat4    offset = assimp_mat4_cast( bone->mOffsetMatrix );
    203                 const char* name = bone->mName.data;
    204                 bones[m].name = make_name( name );
    205                 bones[m].transform = offset;
    206         }
    207         return true;
     249        if ( m_data->scene != nullptr ) aiReleaseImport( m_data->scene );
     250        delete m_data;
    208251}
    209252
    210253void nv::assimp_loader::scene_report() const
    211254{
    212         const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
    213         if ( scene == nullptr ) return;
     255        if ( m_data->scene == nullptr ) return;
    214256
    215257        NV_LOG_NOTICE( "------------------------" );
    216         NV_LOG_NOTICE( "Texture   count - ", scene->mNumTextures );
    217         NV_LOG_NOTICE( "Animation count - ", scene->mNumAnimations );
    218         NV_LOG_NOTICE( "Material  count - ", scene->mNumMaterials );
    219         NV_LOG_NOTICE( "Meshes    count - ", scene->mNumMeshes );
     258        NV_LOG_NOTICE( "Texture   count - ", m_data->scene->mNumTextures );
     259        NV_LOG_NOTICE( "Animation count - ", m_data->scene->mNumAnimations );
     260        NV_LOG_NOTICE( "Material  count - ", m_data->scene->mNumMaterials );
     261        NV_LOG_NOTICE( "Meshes    count - ", m_data->scene->mNumMeshes );
    220262        NV_LOG_NOTICE( "------------------------" );
    221263
    222         aiNode* root = scene->mRootNode;
     264        aiNode* root = m_data->scene->mRootNode;
    223265        if (root)
    224266        {
     
    233275        NV_LOG_NOTICE( "------------------------" );
    234276
    235         if ( scene->mNumMeshes > 0 )
    236         {
    237                 for ( nv::uint32 mc = 0; mc < scene->mNumMeshes; mc++ )
    238                 {
    239                         aiMesh* mesh = scene->mMeshes[mc];
    240 
    241                         NV_LOG_NOTICE( "Mesh #", mc, "   - ", string_view( static_cast<char*>( mesh->mName.data ) ) );
     277        if ( m_data->scene->mNumMeshes > 0 )
     278        {
     279                for ( nv::uint32 mc = 0; mc < m_data->scene->mNumMeshes; mc++ )
     280                {
     281                        aiMesh* mesh = m_data->scene->mMeshes[mc];
     282
     283                        NV_LOG_NOTICE( "Mesh #", mc, "   - ", string_view( static_cast<char*>( mesh->mName.data ), mesh->mName.length ) );
    242284                        NV_LOG_NOTICE( "  bones   - ", mesh->mNumBones );
    243285                        NV_LOG_NOTICE( "  uvs     - ", mesh->mNumUVComponents[0] );
     
    259301        NV_LOG_NOTICE( "------------------------" );
    260302
     303        for ( auto node : m_data->nodes )
     304        {
     305                NV_LOG_NOTICE( "Node : ", string_view( node->mName.data, node->mName.length ) );
     306        }
     307
     308        for ( auto skeleton : m_data->skeletons )
     309        {
     310                NV_LOG_NOTICE( "Skeleton : ", string_view( skeleton->mName.data, skeleton->mName.length ) );
     311        }
    261312
    262313        //      if ( scene->mNumMaterials > 0 )
     
    283334}
    284335
    285 data_node_list* nv::assimp_loader::release_merged_bones( data_channel_set* meshes )
    286 {
    287         const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
    288         data_node_list* result = new data_node_list( make_name( "bones" ) );
    289         hash_store< shash64, uint16 > names;
     336bool nv::assimp_loader::is_node_animated()
     337{
     338        return is_animated() && m_data->skeletons.empty();
     339}
     340
     341void nv::assimp_loader::build_skeleton( vector< data_node_info >& skeleton, const void* node, int parent_id )
     342{
     343        const aiNode* ainode = reinterpret_cast<const aiNode*>( node );
     344
     345        if ( ainode->mNumMeshes > 0 )
     346        {
     347                int error;
     348                int bug_this_works_only_if_before_releasing_meshes;
     349
     350                nv::uint32 mid = ainode->mMeshes[0];
     351                m_mesh_info[mid].parent_id = parent_id;
     352                return;
     353        }
     354
     355        string_view name( ainode->mName.data, ainode->mName.length );
     356        if ( name.starts_with( '_' ) ) return;
     357
     358        data_node_info info;
     359        info.name      = make_name( name );
     360        info.parent_id = parent_id;
     361
     362        int this_id = skeleton.size();
     363        skeleton.push_back( info );
     364        for ( unsigned i = 0; i < ainode->mNumChildren; ++i )
     365        {
     366                build_skeleton( skeleton, ainode->mChildren[i], this_id );
     367        }
     368}
     369
     370data_node_list* nv::assimp_loader::release_merged_bones()
     371{
     372        if ( m_data->skeletons.empty() ) return nullptr;
     373        vector< data_node_info > bone_data;
     374        hash_store< shash64, uint16 > bone_map;
     375
     376        {
     377                const aiNode* skeleton = m_data->skeletons[0];
     378                build_skeleton( bone_data, skeleton, -1 );
     379
     380                for ( uint32 i = 0; i < bone_data.size(); ++i )
     381                {
     382                        bone_map[bone_data[i].name] = uint16(i);
     383                }
     384        }
     385
    290386        for ( unsigned int m = 0; m < m_mesh_count; ++m )
    291387        {
    292388                uint16 translate[MAX_BONES];
    293389                vector< data_node_info > bones;
    294                 const aiMesh*  mesh  = scene->mMeshes[ m ];
     390                const aiMesh*  mesh = m_data->scene->mMeshes[m];
    295391                if ( mesh->mNumBones != 0 )
    296392                {
    297                         bones.resize( mesh->mNumBones );
    298                         NV_ASSERT( false, "parent ids for bones are not loaded!" );
    299                         load_bones( m, bones );
    300                         for ( unsigned int b = 0; b < mesh->mNumBones; ++b )
     393                        for ( unsigned int b = 0; b < mesh->mNumBones; b++ )
    301394                        {
    302 
    303                                 data_node_info bone = bones[b];
    304                                 auto iname = names.find( bone.name );
    305                                 if ( iname == names.end() )
     395                                aiBone* bone = mesh->mBones[b];
     396                                mat4    offset = assimp_mat4_cast( bone->mOffsetMatrix );
     397                                shash64 bone_name( bone->mName.data );
     398
     399                                int remove_this;
     400
     401                                NV_ASSERT( bone_map.find( shash64( bone->mName.data ) ) != bone_map.end(), "BONE NOT FOUND!" );
     402                                uint16 index = bone_map[bone_name];
     403                                bone_data[index].transform = offset;
     404                                translate[b] = index;
     405                        }
     406
     407                        data_channel_access< assimp_skinned_vtx > channel( const_cast<raw_data_channel*>( m_meshes[m]->get_channel( 0 ) ) );
     408                        for ( unsigned v = 0; v < channel.size(); ++v )
     409                        {
     410                                assimp_skinned_vtx& vertex = channel.data()[v];
     411                                for ( int i = 0; i < 4; ++i )
    306412                                {
    307                                         NV_ASSERT( result->size() < MAX_BONES, "Too many bones to merge!" );
    308                                         uint16 index = uint16( result->size() );
    309                                         result->append( bone );
    310                                         names[ bone.name ] = index;
    311                                         translate[b] = index;
    312                                 }
    313                                 else
    314                                 {
    315                                         translate[b] = iname->second;
    316                                 }
    317                         }
    318                         if ( m > 0 && bones.size() > 0 )
    319                         {
    320                                 data_channel_access< assimp_skinned_vtx > channel( const_cast< raw_data_channel* >( meshes[m].get_channel(0) ) );
    321                                 for ( unsigned v = 0; v < channel.size(); ++v )
    322                                 {
    323                                         assimp_skinned_vtx& vertex = channel.data()[v];
    324 
    325                                         for ( int i = 0 ; i < 4; ++i)
     413                                        if ( vertex.boneweight[i] > 0.0f )
    326414                                        {
    327                                                 if ( vertex.boneweight[i] > 0.0f )
    328                                                 {
    329                                                         vertex.boneindex[i] = int( translate[vertex.boneindex[i]] );
    330                                                 }
     415                                                vertex.boneindex[i] = int( translate[vertex.boneindex[i]] );
    331416                                        }
    332417                                }
    333418                        }
    334                 }       
    335         }
    336         //result->initialize();
    337 
    338         return result;
     419
     420                }
     421        }
     422
     423        for ( uint32 i = 0; i < bone_data.size(); ++i )
     424        {
     425                int error; // not really, just
     426                int check_this_shit;
     427                if ( bone_data[i].transform == mat4() )
     428                {
     429                        mat4 tr = nv::math::inverse( assimp_mat4_cast( m_data->node_by_name[bone_data[i].name]->mTransformation ) );
     430                        bone_data[i].transform = tr * bone_data[bone_data[i].parent_id].transform;
     431                }
     432//              list->append( bone_data[i] );
     433        }
     434
     435
     436        data_node_list* list = new data_node_list( make_name( "bones" ) );
     437        for ( uint32 i = 0; i < bone_data.size(); ++i )
     438        {
     439                list->append( bone_data[i] );
     440        }
     441
     442        return list;
    339443}
    340444
    341445mesh_nodes_data* nv::assimp_loader::release_mesh_nodes_data( size_t index /*= 0*/ )
    342446{
    343         if ( m_scene == nullptr ) return nullptr;
    344         const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
     447        if ( m_data->scene == nullptr ) return nullptr;
     448        const aiScene* scene = reinterpret_cast<const aiScene*>( m_data->scene );
    345449        if ( scene->mRootNode == nullptr || scene->mAnimations == nullptr || scene->mAnimations[index] == nullptr) return nullptr;
    346450
     
    349453
    350454        uint32 count = count_nodes( scene->mRootNode );
     455        count = count - 1;
    351456
    352457        uint16 frame_rate     = static_cast<uint16>( anim->mTicksPerSecond );
    353         uint16 duration       = static_cast<uint16>( anim->mDuration );
     458        uint16 duration       = static_cast<uint16>( anim->mDuration )+1;
    354459
    355460        data_channel_set** temp  = new data_channel_set*[ count ];
    356         data_node_info*    temp2 = new data_node_info[count];
     461        data_node_info*    temp2 = new data_node_info[count ];
    357462        array_ref< data_channel_set* > temp_ref( temp, count );
    358463        array_ref< data_node_info >    temp2_ref( temp2, count );
    359         load_node( index, temp_ref, temp2_ref, root, 0, -1 );
     464
     465        nv::sint16 next = 0;
     466        for ( unsigned i = 0; i < scene->mRootNode->mNumChildren; ++i )
     467        {
     468                next = load_node( index, temp_ref, temp2_ref, scene->mRootNode->mChildren[i], next, -1 );
     469        }
     470//      load_node( index, temp_ref, temp2_ref, scene->mRootNode, 0, -1 );
    360471
    361472        mesh_nodes_data* result = new mesh_nodes_data( make_name( static_cast<const char*>( anim->mName.data ) ), frame_rate, duration );
     
    372483data_node_list* nv::assimp_loader::release_data_node_list( size_t index /*= 0 */ )
    373484{
     485        return release_merged_bones();
     486}
     487
     488bool nv::assimp_loader::is_animated( size_t /*= 0 */ )
     489{
    374490        int this_is_incorrect;
    375         NV_ASSERT( false, "unimplemented!" );
    376 //      mesh_nodes_data* half_result = release_mesh_nodes_data( index );
    377 //      data_node_list* result = new data_node_list( half_result->get_name() );
    378 //      for ( auto node : *half_result )
    379 //              result->append( node->get_info() );
    380 //      delete half_result;
    381 //      return result;
    382         return nullptr;
    383 }
    384 
    385 bool nv::assimp_loader::is_animated( size_t /*= 0 */ )
    386 {
    387         int this_is_incorrect;
    388         return false;
     491        return m_mesh_count == 0 || m_data->scene->mNumAnimations > 0 && m_data->skeletons.size() == 0;
     492}
     493
     494int indent = 0;
     495
     496void nv::assimp_loader::scan_nodes( const void* node ) const
     497{
     498        const aiNode* ainode = reinterpret_cast<const aiNode*>( node );
     499        m_data->nodes.push_back( ainode );
     500        m_data->node_by_name[shash64(ainode->mName.data)] = ainode;
     501
     502        for ( unsigned i = 0; i < ainode->mNumChildren; ++i )
     503        {
     504                scan_nodes( ainode->mChildren[i] );
     505        }
    389506}
    390507
     
    402519nv::sint16 nv::assimp_loader::load_node( uint32 anim_id, array_ref< data_channel_set* > nodes, array_ref< data_node_info > infos, const void* vnode, sint16 this_id, sint16 parent_id )
    403520{
    404         const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
    405521        const aiNode*  node  = reinterpret_cast<const aiNode*>( vnode );
    406522        string_view name( static_cast< const char* >( node->mName.data ) );
    407         const aiAnimation* anim  = scene->mAnimations[anim_id];
     523        const aiAnimation* anim  = m_data->scene->mAnimations[anim_id];
    408524        const aiNodeAnim*  anode = nullptr;
    409525
     
    415531        }
    416532
    417         nodes[ this_id ] = anode ? create_keys( anode ) : data_channel_set_creator::create_set( 0 );
     533
     534        transform t = nv::transform( nv::assimp_mat4_cast( node->mTransformation ) );
     535
     536        nodes[ this_id ] = anode ? create_keys( anode, t ) : data_channel_set_creator::create_set( 0 );
    418537
    419538        infos[this_id].name      = make_name( name );
     
    424543        //       node's without keys
    425544        // TODO: this can probably be deleted
    426         infos[this_id].transform = nv::assimp_mat4_cast( node->mTransformation );
    427         if ( this_id == 0 ) infos[this_id].transform = mat4();
     545//      infos[this_id].transform = nv::assimp_mat4_cast( node->mTransformation );
     546//      if ( this_id == 0 ) infos[this_id].transform = mat4();
     547
    428548
    429549        nv::sint16 next = this_id + 1;
     
    436556}
    437557
    438 data_channel_set* nv::assimp_loader::create_keys( const void* vnode )
    439 {
    440         const aiNodeAnim* node = reinterpret_cast< const aiNodeAnim* >( vnode );
     558data_channel_set* nv::assimp_loader::create_keys( const void* vnode, const transform& tr )
     559{
     560        const aiNodeAnim* node  = reinterpret_cast< const aiNodeAnim* >( vnode );
    441561        if ( node->mNumPositionKeys == 0 && node->mNumRotationKeys == 0 && node->mNumScalingKeys == 0 )
    442562        {
    443563                return data_channel_set_creator::create_set( 0 );
    444564        }
    445        
     565
     566/* OLD
    446567        data_channel_set* set = data_channel_set_creator::create_set( 2 );
    447568        data_channel_set_creator key_set( set );
     
    461582                rchannel[np].rotation = assimp_quat_cast(node->mRotationKeys[np].mValue );
    462583        }
     584        */
     585        data_channel_set* set = data_channel_set_creator::create_set( 1 );
     586        data_channel_set_creator key_set( set );
     587
     588        assimp_key_tr* channel = key_set.add_channel< assimp_key_tr >( node->mNumPositionKeys ).data();
     589        for ( unsigned np = 0; np < node->mNumPositionKeys; ++np )
     590        {
     591                channel[np].tform.set_position( assimp_vec3_cast( node->mPositionKeys[np].mValue ) );
     592                channel[np].tform.set_orientation( assimp_quat_cast( node->mRotationKeys[np].mValue ) );
     593                if ( is_node_animated() )
     594                        channel[np].tform = tr.inverse() * channel[np].tform ;
     595        }
     596
    463597//      if ( node->mNumScalingKeys > 0 )
    464598//      {
     
    503637nv::size_t nv::assimp_loader::get_nodes_data_count() const
    504638{
    505         if ( m_scene == nullptr ) return 0;
    506         const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
    507         return scene->mNumAnimations;   
    508 }
    509 
    510 
     639        if ( m_data->scene == nullptr ) return 0;
     640        return m_data->scene->mNumAnimations;
     641}
     642
     643
Note: See TracChangeset for help on using the changeset viewer.