Changeset 284


Ignore:
Timestamp:
07/20/14 23:45:56 (11 years ago)
Author:
epyon
Message:
  • nmd format made more robust
  • full implementation of runtime animation format decoding
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/formats/assimp_loader.hh

    r282 r284  
    7070        {
    7171        public:
    72                 assimp_loader( const string& a_ext, const mat4& a_rotate_transform, float a_scale, uint32 a_assimp_flags = 0 );
     72                assimp_loader( const string& a_ext, const mat3& a_rotate_transform, float a_scale, uint32 a_assimp_flags = 0 );
    7373                explicit assimp_loader( const string& a_ext, uint32 a_assimp_flags = 0 );
    7474                virtual bool load( stream& source );
     
    8181                void scene_report() const;
    8282        private:
     83                void initialize( const string& a_ext, const mat3& a_rotate_transform, float a_scale, uint32 a_assimp_flags );
    8384                uint32 load_node( assimp_animation* data, const void* vnode, sint32 this_id, sint32 parent_id );
    8485                uint32 count_nodes( const void* node ) const;
     
    8889                string_table_creator m_strings;
    8990                string m_ext;
    90                 mat4   m_rotate_transform;
     91                mat3   m_r33;
     92                mat3   m_ri33;
    9193                float  m_scale;
    9294                uint32 m_assimp_flags;
  • trunk/nv/formats/nmd_loader.hh

    r283 r284  
    2727        };
    2828
    29         enum class nmd_key_type : uint16
    30         {
    31                 NONE,
    32                 TRANSFORM,
    33         };
    34 
    3529        struct nmd_header
    3630        {
     
    4337        {
    4438                nmd_type type;
     39                uint16   name;
    4540                uint16   children;
    4641                uint32   size;
     
    5651        struct nmd_animation_node_header
    5752        {
    58                 uint16 name;
    5953                sint16 parent_id;
    6054                mat4   transform;
     
    143137        private:
    144138                void reset();
    145                 bool load_mesh( stream& source, uint32 children );
    146                 bool load_bones( stream& source, uint32 children );
     139                bool load_mesh( stream& source, const nmd_element_header& e );
     140                bool load_bones( stream& source, const nmd_element_header& e );
    147141                bool load_strings( stream& source );
    148                 bool load_animation( stream& source, uint32 children );
     142                bool load_animation( stream& source, const nmd_element_header& e );
    149143
    150144                nmd_animation*            m_animation;
  • trunk/nv/gfx/animation.hh

    r282 r284  
    5151                        return result;
    5252                }
     53
     54                uint32 interpolate_raw( float time, float* result ) const
     55                {
     56                        uint32 keyfsize   = desc.size / 4;
     57                        uint32 keyfresult = keyfsize;
     58                        const float* fdata = (const float*)data;
     59                        if ( count == 0 ) return 0;
     60
     61                        uint32 slot = 0;
     62                        int index    = -1;
     63                        float factor = 1.0f;
     64                        if ( desc.slots[0].vslot == animation_slot::TIME )
     65                        {
     66                                slot++;
     67                                keyfresult--;
     68                                if ( count == 1 )
     69                                {
     70                                        std::copy_n( fdata + 1, keyfresult, result );
     71                                        return keyfresult;
     72                                }
     73                                uint32 toffset = desc.slots[0].offset / 4;
     74                                for ( int i = 0 ; i < (int)count - 1 ; i++ )
     75                                {
     76                                        if ( time < fdata[ i * keyfsize + keyfsize + toffset ] ) { index = i; break; }
     77                                }
     78                                NV_ASSERT( index >= 0, "animation time fail!");
     79                                float time0  = fdata[ index * keyfsize + toffset ];
     80                                float time1  = fdata[ index * keyfsize + keyfsize + toffset ];
     81                                float delta  = time1 - time0;
     82                                factor = glm::clamp( (time - time0) / delta, 0.0f, 1.0f );
     83                        }
     84                        else
     85                        {
     86                                if ( count == 1 )
     87                                {
     88                                        std::copy_n( fdata, keyfresult, result );
     89                                        return keyfresult;
     90                                }
     91                                index  = glm::clamp<int>( int( time ), 0, count - 2 );
     92                                factor = glm::clamp<float> ( time - index, 0.0f, 1.0f );
     93                        }
     94                        uint32 ret = 0;
     95                        for ( ; slot < desc.count; ++slot )
     96                        {
     97                                ret += nv::interpolate_raw(
     98                                        desc.slots[slot], factor,
     99                                        fdata + index * keyfsize + desc.slots[slot].offset / 4,
     100                                        fdata + index * keyfsize + keyfsize + desc.slots[slot].offset / 4,
     101                                        result + ret );
     102                        }
     103                        return ret;
     104                }
    53105        };
    54106
     
    62114                        NV_ASSERT( channel, "nullptr passed to add_channel!" );
    63115                        m_channels.push_back( channel );
    64                 }
     116                        for ( uint16 i = 0; i < channel->desc.count; ++i )
     117                        {
     118                                const key_descriptor_slot& ksi = channel->desc.slots[i];
     119                                if ( ksi.vslot != animation_slot::TIME )
     120                                {
     121                                        uint32 index = final_key.count;
     122                                        final_key.slots[ index ].offset = final_key.size;
     123                                        final_key.slots[ index ].etype  = ksi.etype;
     124                                        final_key.slots[ index ].vslot  = ksi.vslot;
     125                                        final_key.size += get_datatype_info( ksi.etype ).size;
     126                                        final_key.count++;
     127                                }
     128                        }
     129                }
     130
     131                mat4 get_matrix( float time ) const
     132                {
     133                        float key[ 16 ];
     134                        float* pkey = key;
     135                        for ( uint16 i = 0; i < m_channels.size(); ++i )
     136                        {
     137                                pkey += m_channels[i]->interpolate_raw( time, pkey );
     138                        }
     139                        return extract_matrix_raw( final_key, key );
     140                };
     141
     142                transform get_transform( float time ) const
     143                {
     144                        float key[ 16 ];
     145                        float* pkey = key;
     146                        for ( uint16 i = 0; i < m_channels.size(); ++i )
     147                        {
     148                                pkey += m_channels[i]->interpolate_raw( time, pkey );
     149                        }
     150                        return extract_transform_raw( final_key, key );
     151                };
    65152
    66153                virtual ~key_data()
     
    69156                }
    70157        private:
     158                key_descriptor final_key;
    71159                std::vector< key_raw_channel* > m_channels;
    72160        };
  • trunk/nv/interface/vertex.hh

    r282 r284  
    663663        }
    664664
     665        inline uint32 interpolate_raw_linear( uint32 count, float factor, const float* k1, const float* k2, float* result )
     666        {
     667                for ( uint32 i = 0; i < count; ++i )
     668                {
     669                        result[i] = k1[i] + factor * (k2[i] - k1[i]);
     670                }
     671                return count;
     672        }
     673
     674        inline uint32 interpolate_raw_quat( float factor, const float* k1, const float* k2, float* result )
     675        {
     676                *((quat*)(result)) = interpolate( *((quat*)(k1)), *((quat*)(k2)), factor );
     677                return 4;
     678        }
     679
     680        inline uint32 interpolate_raw( const key_descriptor_slot& slot, float factor, const float* k1, const float* k2, float* result )
     681        {
     682                uint32 count = get_datatype_info( slot.etype ).elements;
     683                switch ( slot.vslot )
     684                {
     685                case animation_slot::TIME:     return 0;
     686                case animation_slot::POSITION: return interpolate_raw_linear( count, factor, k1, k2, result );
     687                case animation_slot::ROTATION: return interpolate_raw_quat( factor, k1, k2, result );
     688                case animation_slot::SCALE:    return interpolate_raw_linear( count, factor, k1, k2, result );
     689                case animation_slot::TFORM:    return
     690                                                                                   interpolate_raw_linear( 3, factor, k1, k2, result ) +
     691                                                                                   interpolate_raw_quat( factor, k1 + 3, k2 + 3, result + 3 );
     692                default:
     693                        return 0;
     694                };
     695        }
     696
     697        inline quat make_quat_fixed( const float* data )
     698        {
     699                quat result;
     700                memcpy((float*)(&result), data, sizeof(quat));
     701                return result;
     702        }
     703
     704        inline mat4 extract_matrix_raw( const key_descriptor& desc, const float* data )
     705        {
     706                if ( desc.count == 1 )
     707                {
     708                        switch ( desc.slots[0].vslot )
     709                        {
     710                        case animation_slot::TIME:     return mat4();
     711                        case animation_slot::POSITION: return glm::translate( mat4(),glm::make_vec3( data ) );
     712                        case animation_slot::ROTATION: return glm::mat4_cast( make_quat_fixed( data ) );
     713                        case animation_slot::SCALE:    return glm::scale( mat4(),glm::make_vec3( data ) );
     714                        case animation_slot::TFORM:    return transform( glm::make_vec3( data ), make_quat_fixed( data + 3 ) ).extract();
     715                        default:
     716                                return mat4();
     717                        };
     718                }
     719                else
     720                {
     721                        mat4 position;
     722                        mat4 rotation;
     723                        mat4 scale;
     724                        for ( uint32 i = 0; i < desc.count; ++i )
     725                        {
     726                                uint32 offset = desc.slots[i].offset / 4;
     727                                switch ( desc.slots[i].vslot )
     728                                {
     729                                case animation_slot::TIME:     break;
     730                                case animation_slot::POSITION:
     731                                        position = glm::translate( position,glm::make_vec3( data + offset ) ); break;
     732                                case animation_slot::ROTATION:
     733                                        rotation = glm::mat4_cast( make_quat_fixed( data + offset ) ); break;
     734                                case animation_slot::SCALE:   
     735                                        scale    = glm::scale( mat4(),glm::make_vec3( data + offset ) ); break;
     736                                case animation_slot::TFORM:    return transform( glm::make_vec3( data + offset ), make_quat_fixed( data + offset + 3 ) ).extract();
     737                                default:
     738                                        break;
     739                                }
     740                        }
     741                        return position * rotation * scale;
     742                }
     743        }
     744
     745        inline transform extract_transform_raw( const key_descriptor& desc, const float* data )
     746        {
     747                if ( desc.count == 1 )
     748                {
     749                        switch ( desc.slots[0].vslot )
     750                        {
     751                        case animation_slot::TIME:     return transform();
     752                        case animation_slot::POSITION: return transform( glm::make_vec3( data ) );
     753                        case animation_slot::ROTATION: return transform( make_quat_fixed( data ) );
     754                        case animation_slot::SCALE:    return transform();
     755                        case animation_slot::TFORM:    return transform( glm::make_vec3( data ), make_quat_fixed( data + 3 ) );
     756                        default:
     757                                return transform();
     758                        };
     759                }
     760                else
     761                {
     762                        vec3 position;
     763                        quat rotation;
     764                        for ( uint32 i = 0; i < desc.count; ++i )
     765                        {
     766                                uint32 offset = desc.slots[i].offset / 4;
     767                                switch ( desc.slots[i].vslot )
     768                                {
     769                                case animation_slot::TIME:     break;
     770                                case animation_slot::POSITION:
     771                                        position = glm::make_vec3( data + offset ); break;
     772                                case animation_slot::ROTATION:
     773                                        rotation = make_quat_fixed( data + offset ); break;
     774                                case animation_slot::SCALE:        break;
     775                                case animation_slot::TFORM:    return transform( glm::make_vec3( data + offset ), make_quat_fixed( data + 3 ) );
     776                                default:
     777                                        break;
     778                                }
     779                        }
     780                        return transform( position, rotation );
     781                }
     782        }
     783
    665784}
    666785
  • trunk/src/formats/assimp_loader.cc

    r282 r284  
    1515const int MAX_BONES = 64;
    1616
    17 nv::assimp_loader::assimp_loader( const string& a_ext, const mat4& a_rotate_transform, float a_scale, uint32 a_assimp_flags /*= 0 */ ) : m_ext( a_ext ), m_rotate_transform( a_rotate_transform ), m_scale( a_scale ), m_assimp_flags( a_assimp_flags ), m_mesh_count(0), m_scene( nullptr )
    18 {
     17nv::assimp_loader::assimp_loader( const string& a_ext, const mat3& a_rotate_transform, float a_scale, uint32 a_assimp_flags /*= 0 */ ) : m_mesh_count(0), m_scene( nullptr )
     18{
     19        initialize( a_ext, a_rotate_transform, a_scale, a_assimp_flags );
     20}
     21
     22nv::assimp_loader::assimp_loader( const string& a_ext, uint32 a_assimp_flags /*= 0 */ ) : m_mesh_count(0), m_scene( nullptr )
     23{
     24        initialize( a_ext, mat3(), 1.0f, a_assimp_flags );
     25}
     26
     27
     28void nv::assimp_loader::initialize( const string& a_ext, const mat3& a_rotate_transform, float a_scale, uint32 a_assimp_flags )
     29{
     30        m_ext   = a_ext;
     31        m_r33   = a_rotate_transform;
     32        m_ri33  = glm::transpose( m_r33 );
     33        m_scale = a_scale;
     34        m_assimp_flags = a_assimp_flags;
    1935        if ( m_assimp_flags == 0 )
    2036        {
     
    3652}
    3753
    38 nv::assimp_loader::assimp_loader( const string& a_ext, uint32 a_assimp_flags /*= 0 */ ) : m_ext( a_ext ), m_rotate_transform(), m_scale( 1.0f ), m_assimp_flags( a_assimp_flags ), m_mesh_count(0), m_scene( nullptr )
    39 {
    40         if ( m_assimp_flags == 0 )
    41         {
    42                 m_assimp_flags = (
    43                         aiProcess_CalcTangentSpace                              | 
    44                         aiProcess_GenSmoothNormals                              | 
    45                         aiProcess_JoinIdenticalVertices                 |   
    46                         aiProcess_ImproveCacheLocality                  | 
    47                         aiProcess_LimitBoneWeights                              | 
    48                         aiProcess_RemoveRedundantMaterials      | 
    49                         aiProcess_SplitLargeMeshes                              | 
    50                         aiProcess_Triangulate                                   | 
    51                         aiProcess_GenUVCoords                   | 
    52                         aiProcess_SortByPType                   | 
    53                         aiProcess_FindDegenerates               | 
    54                         aiProcess_FindInvalidData               | 
    55                         0 );
    56         }
    57 }
     54
    5855bool nv::assimp_loader::load( stream& source )
    5956{
     
    8683        const aiMesh*  mesh  = scene->mMeshes[ index ];
    8784
    88         mat3 scaled_rotatation = glm::mat3( glm::scale( m_scale, m_scale, m_scale ) * m_rotate_transform );
    89         //mat3 scaled_rotatation = glm::mat3( m_rotate_transform );
    9085        vec3 vertex_offset     = glm::vec3();
    91         mat3 vertex_transform  = scaled_rotatation;
    92         mat3 normal_transform  = glm::mat3( m_rotate_transform );
     86        mat3 vertex_transform  = m_scale * m_r33;
     87        mat3 normal_transform  = m_r33;
    9388
    9489        bool skinned = mesh->mNumBones > 0;
     
    170165        if ( mesh->mNumBones == 0 ) return false;
    171166
    172         mat4 bone_transform    = glm::scale( 1.f/m_scale, 1.f/m_scale, 1.f/m_scale ) *  glm::inverse( glm::mat4(m_rotate_transform) );
    173         mat4 bone_pre_transform    = glm::scale( m_scale, m_scale, m_scale );
     167        mat4 bone_transform     = mat4( ( 1.f/m_scale * m_ri33 ) );
     168        mat4 bone_pre_transform = mat4( m_scale * m_r33 );
    174169
    175170        for (unsigned int m=0; m<mesh->mNumBones; m++)
     
    291286                        }
    292287                }
    293                 if ( m > 0 )
     288                if ( m > 0 && bones.size() > 0 )
    294289                {
    295290                        mesh_data* mesh = model->meshes[m];
     
    318313        if ( m_scene == nullptr ) return nullptr;
    319314        const aiScene* scene = (const aiScene*)m_scene;
    320         if ( scene->mRootNode == nullptr || scene->mAnimations[0] == nullptr ) return nullptr;
     315        if ( scene->mRootNode == nullptr || scene->mAnimations == nullptr || scene->mAnimations[0] == nullptr) return nullptr;
    321316        assimp_animation* result = new assimp_animation;
    322317
     
    370365        //       node's without keys
    371366        a_data.transform = nv::assimp_mat4_cast( node->mTransformation );
     367        if (this_id == 0)
     368                a_data.transform = mat4();
    372369        a_data.channel_count = 0;
    373370
     
    405402                size_t pn = glm::min( node->mNumPositionKeys - 1, n );
    406403                size_t rn = glm::min( node->mNumRotationKeys - 1, n );
    407                 nv::vec3 pos = nv::assimp_vec3_cast(node->mPositionKeys[pn].mValue);
    408                 nv::quat rot = nv::assimp_quat_cast(node->mRotationKeys[rn].mValue);
     404                nv::vec3 pos = m_r33 * nv::assimp_vec3_cast(node->mPositionKeys[pn].mValue) * m_scale;
     405                nv::quat rot = glm::quat_cast( m_r33 * glm::mat3_cast( assimp_quat_cast(node->mRotationKeys[rn].mValue ) ) * m_ri33 );
    409406                // TODO: only do the calculation when a rotate transform is present!
    410                 nv::transform ptr( vec3(), glm::quat_cast( m_rotate_transform ) );
     407                nv::transform ptr;
    411408                if ( parent )
    412409                {
     
    417414                        }
    418415                }
    419                 nv::transform key( ptr * nv::transform( pos * m_scale, rot ) );
     416
     417                nv::transform key( ptr * nv::transform( pos, rot ) );
    420418                channel[n].tform = key;
    421419        }
     
    425423{
    426424        data->channel_count = 0;
    427         // TODO : support for m_rotate_transform and m_scale! ( should be easy )
    428425        const aiNodeAnim* node = (const aiNodeAnim*)vnode;
    429426        if ( node->mNumPositionKeys == 0 && node->mNumRotationKeys == 0 && node->mNumScalingKeys == 0 )
     
    443440        {
    444441                pchannel[np].time     = (float)node->mPositionKeys[np].mTime;
    445                 pchannel[np].position = assimp_vec3_cast(node->mPositionKeys[np].mValue);
     442                pchannel[np].position = m_r33 * assimp_vec3_cast(node->mPositionKeys[np].mValue) * m_scale;
    446443        }
    447444        for ( unsigned np = 0; np < node->mNumRotationKeys; ++np )
    448445        {
    449446                rchannel[np].time     = (float)node->mRotationKeys[np].mTime;
    450                 rchannel[np].rotation = assimp_quat_cast(node->mRotationKeys[np].mValue);
     447                rchannel[np].rotation = glm::quat_cast( m_r33 * glm::mat3_cast( assimp_quat_cast(node->mRotationKeys[np].mValue ) ) * m_ri33 );
    451448        }
    452449        if ( node->mNumScalingKeys > 0 )
     
    463460                        }
    464461                }
    465         }
    466 }
    467 
     462                else
     463                {
     464                        schannel[0].time  = (float)node->mScalingKeys[0].mTime;
     465                        schannel[0].scale = assimp_vec3_cast(node->mScalingKeys[0].mValue);
     466                }
     467        }
     468
     469}
     470
  • trunk/src/formats/nmd_loader.cc

    r283 r284  
    2222                switch ( element_header.type )
    2323                {
    24                 case nmd_type::MESH           : load_mesh( source, element_header.children ); break;
    25                 case nmd_type::ANIMATION      : load_animation( source, element_header.children ); break;
    26                 case nmd_type::BONE_ARRAY     : load_bones( source, element_header.children ); break;
     24                case nmd_type::MESH           : load_mesh( source, element_header ); break;
     25                case nmd_type::ANIMATION      : load_animation( source, element_header ); break;
     26                case nmd_type::BONE_ARRAY     : load_bones( source, element_header ); break;
    2727                case nmd_type::STRING_TABLE   : load_strings( source ); break;
    2828                default: NV_ASSERT( false, "UNKNOWN NMD ELEMENT!" ); break;
     
    3232}
    3333
    34 bool nv::nmd_loader::load_mesh( stream& source, uint32 children )
     34bool nv::nmd_loader::load_mesh( stream& source, const nmd_element_header& e )
    3535{
    3636        mesh_data* mesh = new mesh_data();
    37         for ( uint32 s = 0; s < children; ++s )
     37        for ( uint32 s = 0; s < e.children; ++s )
    3838        {
    3939                nmd_element_header element_header;
     
    8282}
    8383
    84 bool nv::nmd_loader::load_bones( stream& source, uint32 children )
     84bool nv::nmd_loader::load_bones( stream& source, const nmd_element_header& e )
    8585{
    8686        NV_ASSERT( m_bone_data == nullptr, "MULTIPLE BONE ENTRIES!" );
    8787        m_bone_data = new nmd_bone_data;
    88         m_bone_data->bones = new nmd_bone[ children ];
    89         m_bone_data->count = (uint16)children;
    90         source.read( m_bone_data->bones, sizeof( nmd_bone ), children );
     88        m_bone_data->bones = new nmd_bone[ e.children ];
     89        m_bone_data->count = (uint16)e.children;
     90        source.read( m_bone_data->bones, sizeof( nmd_bone ), e.children );
    9191        return true;
    9292}
     
    114114
    115115
    116 bool nv::nmd_loader::load_animation( stream& source, uint32 children )
     116bool nv::nmd_loader::load_animation( stream& source, const nmd_element_header& e )
    117117{
    118118        NV_ASSERT( m_animation == nullptr, "MULTIPLE ANIMATION ENTRIES!" );
     
    123123        m_animation->duration   = header.duration;
    124124        m_animation->flat       = header.flat;
    125         m_animation->node_count = (uint16)children;
    126         m_animation->nodes      = new nmd_node[ children ];
    127         for ( uint32 i = 0; i < children; ++i )
     125        m_animation->node_count = (uint16)e.children;
     126        m_animation->nodes      = new nmd_node[ e.children ];
     127        for ( uint32 i = 0; i < e.children; ++i )
    128128        {
    129129                nmd_element_header element_header;
    130130                source.read( &element_header, sizeof( element_header ), 1 );
    131131                NV_ASSERT( element_header.type == nmd_type::ANIMATION_NODE, "ANIMATION_NODE expected!" );
     132                m_animation->nodes[i].name          = element_header.name;
    132133
    133134                uint16 ch_count = element_header.children;
     
    135136                nmd_animation_node_header node_header;
    136137                source.read( &node_header, sizeof( node_header ), 1 );
    137                 m_animation->nodes[i].name          = node_header.name;
    138138                m_animation->nodes[i].parent_id     = node_header.parent_id;
    139139                m_animation->nodes[i].transform     = node_header.transform;
Note: See TracChangeset for help on using the changeset viewer.