Ignore:
Timestamp:
05/30/14 18:14:17 (11 years ago)
Author:
epyon
Message:
  • formats/assimp - full animation support
  • two animation formats - merged keys and separate key channels
File:
1 edited

Legend:

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

    r248 r249  
    270270}
    271271
     272assimp_animation* nv::assimp_loader::release_animation( size_t, bool pre_transform, const std::vector< assimp_bone >* bone_data )
     273{
     274        if ( m_scene == nullptr ) return nullptr;
     275        const aiScene* scene = (const aiScene*)m_scene;
     276        if ( scene->mRootNode == nullptr || scene->mAnimations[0] == nullptr ) return nullptr;
     277        assimp_animation* result = new assimp_animation;
     278
     279        // need resize not to copy!
     280        result->nodes.resize( count_nodes( scene->mRootNode ) );
     281
     282        const aiNode*      root = scene->mRootNode;
     283        const aiAnimation* anim = scene->mAnimations[0]; // if implemented, change in load_node also
     284
     285        result->fps            = (float)anim->mTicksPerSecond;
     286        result->duration       = (float)anim->mDuration;
     287        result->pretransformed = pre_transform;
     288
     289        load_node( result, root, 0, -1 );
     290        result->nodes[0].transform = glm::scale( m_scale, m_scale, m_scale ) * result->nodes[0].transform;
     291
     292        if ( bone_data )
     293        {
     294                std::unordered_map< std::string, uint16 > names;
     295                for ( uint16 bi = 0; bi < bone_data->size(); ++bi )
     296                {
     297                        names[ (*bone_data)[bi].name ] = bi;
     298                }
     299
     300                for ( unsigned i = 0; i < result->nodes.size(); ++i )
     301                {
     302                        assimp_animated_node_data& node = result->nodes[i];
     303                        node.bone_id = -1;
     304                        auto bi = names.find( node.name );
     305                        if ( bi != names.end() )
     306                        {
     307                                node.bone_id = bi->second;
     308                        }
     309                        if ( node.parent_id != -1 )
     310                        {
     311                                result->nodes[ node.parent_id ].children.push_back( &node );
     312                        }
     313                }
     314        }
     315
     316        return result;
     317}
     318
     319nv::uint32 nv::assimp_loader::count_nodes( const void* node ) const
     320{
     321        const aiNode* ainode = (const aiNode*)node;
     322        nv::uint32 count = 1;
     323        for ( unsigned i = 0; i < ainode->mNumChildren; ++i )
     324        {
     325                count += count_nodes( ainode->mChildren[i] );
     326        }
     327        return count;
     328}
     329
     330nv::uint32 nv::assimp_loader::load_node( assimp_animation* data, const void* vnode, sint32 this_id, sint32 parent_id )
     331{
     332        const aiScene* scene = (const aiScene*)m_scene;
     333        const aiNode*  node  = (const aiNode*)vnode;
     334        string name( node->mName.data );
     335        const aiAnimation* anim  = scene->mAnimations[0];
     336        const aiNodeAnim*  anode = nullptr;
     337
     338        for ( unsigned i = 0 ; i < anim->mNumChannels ; i++ )
     339        {
     340                anode = anim->mChannels[i];
     341                if ( std::string( anode->mNodeName.data ) == name ) break;
     342                anode = nullptr;
     343        }
     344
     345        assimp_animated_node_data& a_data = data->nodes[ this_id ];
     346
     347        a_data.name      = name;
     348        a_data.parent_id = parent_id;
     349        a_data.bone_id = -1;
     350        a_data.transform = nv::assimp_mat4_cast( node->mTransformation );
     351
     352        if (anode)
     353        {
     354                if ( data->pretransformed )
     355                {
     356                        a_data.keys = create_transformed_keys( anode, parent_id >= 0 ? data->nodes[ parent_id ].keys : nullptr );
     357                }
     358                else
     359                {
     360                        a_data.keys = create_direct_keys( anode );
     361                }
     362        }
     363
     364        nv::uint32 next = this_id + 1;
     365        for ( unsigned i = 0; i < node->mNumChildren; ++i )
     366        {
     367                next = load_node( data, node->mChildren[i], next, this_id );
     368        }
     369        return next;
     370}
     371
     372key_animation_data* nv::assimp_loader::create_transformed_keys( const void* vnode, const key_animation_data* parent_keys )
     373{
     374        const aiNodeAnim* node = (const aiNodeAnim*)vnode;
     375        size_t max_keys = glm::max( node->mNumPositionKeys, node->mNumRotationKeys );
     376        nv::transform_vector* keys = new nv::transform_vector;
     377        for ( unsigned n = 0; n < max_keys; ++n )
     378        {
     379                size_t pn = glm::min( node->mNumPositionKeys - 1, n );
     380                size_t rn = glm::min( node->mNumRotationKeys - 1, n );
     381                nv::vec3 pos = nv::assimp_vec3_cast(node->mPositionKeys[pn].mValue);
     382                nv::quat rot = nv::assimp_quat_cast(node->mRotationKeys[rn].mValue);
     383                nv::transform ptr;
     384                if ( parent_keys )
     385                {
     386                        const nv::transform_vector* pv = (const nv::transform_vector*)parent_keys;
     387                        if ( pv && pv->size() > 0 ) ptr = pv->get( glm::min( n, pv->size()-1 ) );
     388                }
     389
     390                nv::vec3 rot_pos = ptr.get_orientation() * pos;
     391                pos = ptr.get_position() + rot_pos;
     392                rot = glm::normalize( ptr.get_orientation() * rot );
     393                keys->insert( nv::transform( pos, rot ) );
     394        }
     395        return keys;
     396}
     397
     398key_animation_data* nv::assimp_loader::create_direct_keys( const void* vnode )
     399{
     400        const aiNodeAnim* node = (const aiNodeAnim*)vnode;
     401        if ( node->mNumPositionKeys == 0 && node->mNumRotationKeys == 0 && node->mNumScalingKeys == 0 ) return nullptr;
     402        key_vectors_prs* keys = new key_vectors_prs;
     403
     404        for ( unsigned np = 0; np < node->mNumPositionKeys; ++np )
     405        {
     406                keys->insert_position( (float)node->mPositionKeys[np].mTime, assimp_vec3_cast(node->mPositionKeys[np].mValue) );
     407        }
     408        for ( unsigned np = 0; np < node->mNumRotationKeys; ++np )
     409        {
     410                keys->insert_rotation( (float)node->mRotationKeys[np].mTime, assimp_quat_cast(node->mRotationKeys[np].mValue) );
     411        }
     412        if ( node->mNumScalingKeys > 0 )
     413        {
     414                nv::vec3 scale_vec0 = assimp_vec3_cast( node->mScalingKeys[0].mValue );
     415                float scale_value   = glm::length( glm::abs( scale_vec0 - nv::vec3(1,1,1) ) );
     416                if ( node->mNumScalingKeys > 1 || scale_value > 0.001 )
     417                {
     418                        NV_LOG( nv::LOG_WARNING, "scale key significant!" );
     419                        for ( unsigned np = 0; np < node->mNumRotationKeys; ++np )
     420                        {
     421                                keys->insert_scale( (float)node->mScalingKeys[np].mTime, assimp_vec3_cast(node->mScalingKeys[np].mValue) );
     422                        }
     423                }
     424        }
     425        return keys;
     426}
     427
Note: See TracChangeset for help on using the changeset viewer.