Changeset 287 for trunk/src/gfx


Ignore:
Timestamp:
07/23/14 15:24:03 (11 years ago)
Author:
epyon
Message:
  • mesh_data_pack's in every format
  • md5_mesh_data removed, uses standard mesh_data
  • BONE_ARRAY in NMD is now a simple set of animation nodes
  • bone and animation node concepts merged
  • several minor changes
Location:
trunk/src/gfx
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gfx/keyframed_mesh.cc

    r285 r287  
    1515using namespace nv;
    1616
    17 nv::keyframed_mesh::keyframed_mesh( device* a_device, mesh_data* a_data, tag_map* a_tag_map )
     17nv::keyframed_mesh::keyframed_mesh( device* a_device, const mesh_data* a_data, const mesh_nodes_data* a_tag_map )
    1818        : animated_mesh()
    1919        , m_mesh_data( a_data )
     
    4040}
    4141
    42 transform keyframed_mesh::get_tag( uint32 tag ) const
     42transform keyframed_mesh::get_node_transform( uint32 node_id ) const
    4343{
    4444        NV_ASSERT( m_tag_map, "TAGMAP FAIL" );
    45         const key_data* data = m_tag_map->get_tag( tag );
     45        NV_ASSERT( node_id < m_tag_map->get_count(), "TAGMAP FAIL" );
     46        const key_data* data = m_tag_map->get_node( node_id )->data;
    4647        NV_ASSERT( data, "TAG FAIL" );
    4748        transform last = data->get_raw_transform( m_last_frame );
    4849        transform next = data->get_raw_transform( m_next_frame );
    4950        return interpolate( last, next, m_interpolation  );
     51}
     52
     53mat4 keyframed_mesh::get_node_matrix( uint32 node_id ) const
     54{
     55        return get_node_transform( node_id ).extract();
    5056}
    5157
     
    125131}
    126132
    127 nv::keyframed_mesh_gpu::keyframed_mesh_gpu( device* a_device, mesh_data* a_data, tag_map* a_tag_map, program* a_program )
     133nv::keyframed_mesh_gpu::keyframed_mesh_gpu( device* a_device, const mesh_data* a_data, const mesh_nodes_data* a_tag_map, program* a_program )
    128134        : keyframed_mesh( a_device, a_data, a_tag_map )
    129135        , m_loc_next_position( 0 )
     
    159165}
    160166
    161 nv::keyframed_mesh_cpu::keyframed_mesh_cpu( device* a_device, mesh_data* a_data, tag_map* a_tag_map )
     167nv::keyframed_mesh_cpu::keyframed_mesh_cpu( device* a_device, const mesh_data* a_data, const mesh_nodes_data* a_tag_map )
    162168        : keyframed_mesh( a_device, a_data, a_tag_map )
    163169{
  • trunk/src/gfx/skeletal_mesh.cc

    r283 r287  
    1111
    1212
    13 nv::skeletal_mesh::skeletal_mesh( device* a_device, md5_mesh_data* a_mesh_data )
     13nv::skeletal_mesh::skeletal_mesh( device* a_device, const mesh_data* a_mesh_data, const mesh_nodes_data* bones )
    1414        : animated_mesh()
    15         , m_mesh_data( nullptr )
    16 {
    17         m_mesh_data = a_mesh_data->spawn();
     15        , m_data( a_mesh_data )
     16{
     17        const mesh_raw_channel* pnt_chan = a_mesh_data->get_channel<md5_vtx_pnt>();
     18        m_pntdata.assign( (const md5_vtx_pnt*)pnt_chan->data, pnt_chan->count );
     19        m_bone_offset.resize( bones->get_count() );
     20        for ( uint32 i = 0; i < bones->get_count(); ++i )
     21        {
     22                m_bone_offset[i] = transform( bones->get_node(i)->transform );
     23        }
     24        m_vtx_data  = a_mesh_data->get_channel_data<md5_vtx_pntiw>();
     25        m_indices   = a_mesh_data->get_count();
    1826        m_va        = a_device->create_vertex_array( a_mesh_data, nv::STREAM_DRAW );
    1927}
     
    2836                uint32 new_time = a_anim_time % anim_duration;
    2937                anim->update_skeleton( m_transform.data(), (float)new_time * 0.001f );
    30                 m_mesh_data->apply( m_transform.data() );
     38
     39                //m_mesh_data->apply( m_transform.data() );
     40                {
     41                        size_t skeleton_size = m_bone_offset.size();
     42                        size_t vertex_count  = m_pntdata.size();
     43                        m_pos_offset.resize( skeleton_size );
     44                        for ( unsigned int i = 0; i < skeleton_size; ++i )
     45                        {
     46                                m_pos_offset[i] = m_transform[i] * m_bone_offset[i];
     47                        }
     48
     49                        std::fill( m_pntdata.raw_data(), m_pntdata.raw_data() + m_pntdata.raw_size(), 0 );
     50                        for ( unsigned int i = 0; i < vertex_count; ++i )
     51                        {
     52                                const md5_vtx_pntiw& vert = m_vtx_data[i];
     53
     54                                for ( size_t j = 0; j < 4; ++j )
     55                                {
     56                                        int   index  = vert.boneindex[j];
     57                                        float weight = vert.boneweight[j];
     58                                        const quat& orient      = m_transform[index].get_orientation();
     59                                        const transform& offset = m_pos_offset[index];
     60                                        m_pntdata[i].position += offset.transformed( vert.position )        * weight;
     61                                        m_pntdata[i].normal   += ( orient * vert.normal  ) * weight;
     62                                        m_pntdata[i].tangent  += ( orient * vert.tangent ) * weight;
     63                                }
     64                        }
     65                }
     66
    3167                vertex_buffer* vb = m_va->find_buffer( nv::slot::POSITION );
    3268                vb->bind();
    33                 vb->update( m_mesh_data->data(), 0, m_mesh_data->size() );
     69                vb->update( m_pntdata.data(), 0, m_pntdata.raw_size() );
    3470                vb->unbind();
    3571        }
     
    3975{
    4076        delete m_va;
    41         delete m_mesh_data;
    4277}
    4378
     
    5287}
    5388
    54 void nv::skeletal_animation_entry_gpu::update_skeleton( mat4* data, uint32 time )
    55 {
    56         m_animation->animate( data, time );
    57 }
    58 
    59 void nv::skeletal_animation_entry_gpu::prepare( const nmd_temp_model* m_model )
    60 {
    61         m_animation->prepare( m_model );
    62 }
    63 
    64 nv::skeletal_mesh_gpu::skeletal_mesh_gpu( device* a_device, const nmd_temp_model* a_model, uint32 index, bool primary )
    65         : animated_mesh(), m_primary( primary ), m_model( a_model )
    66 {
    67         const mesh_data* data = a_model->get_data( index );
    68         m_va          = a_device->create_vertex_array( data, nv::STATIC_DRAW );
    69         m_index_count = data->get_count();
     89
     90nv::skeletal_animation_entry_gpu::skeletal_animation_entry_gpu( const std::string& name, const mesh_nodes_data* anim, bool a_looping )
     91        : animation_entry( name )
     92        , m_node_data( anim )
     93{
     94        uint32 node_count = m_node_data->get_count();
     95
     96        m_prepared  = false;
     97        m_looping   = a_looping;
     98        m_children  = nullptr;
     99        m_offsets   = nullptr;
     100        m_bone_ids  = new sint16[ node_count ];
     101
     102        if ( !m_node_data->is_flat() )
     103        {
     104                m_children = new std::vector< uint32 >[ node_count ];
     105                for ( uint32 n = 0; n < node_count; ++n )
     106                {
     107                        const mesh_node_data* node = m_node_data->get_node(n);
     108                        if ( node->parent_id != -1 )
     109                        {
     110                                m_children[ node->parent_id ].push_back( n );
     111                        }
     112                }
     113        }
     114}
     115
     116void nv::skeletal_animation_entry_gpu::update_skeleton( mat4* data, uint32 time ) const
     117{
     118        float tick_time = ( time * 0.001f ) * m_node_data->get_frame_rate();
     119        float anim_time = fmodf( tick_time, m_node_data->get_duration() );
     120
     121        if ( !m_node_data->is_flat() )
     122        {
     123                animate_rec( data, anim_time, 0, mat4() );
     124                return;
     125        }
     126
     127        for ( uint32 n = 0; n < m_node_data->get_count(); ++n )
     128                if ( m_bone_ids[n] >= 0 )
     129                {
     130                        const mesh_node_data* node = m_node_data->get_node(n);
     131                        nv::mat4 node_mat( node->transform );
     132
     133                        if ( node->data )
     134                        {
     135                                node_mat = node->data->get_matrix( anim_time );
     136                        }
     137
     138                        sint16 bone_id = m_bone_ids[n];
     139                        data[ bone_id ] = node_mat * m_offsets[ bone_id ];
     140                }
     141}
     142
     143void nv::skeletal_animation_entry_gpu::prepare( const mesh_nodes_data* bones )
     144{
     145        if ( m_prepared ) return;
     146        std::unordered_map< std::string, nv::uint16 > bone_names;
     147        m_offsets = new mat4[ bones->get_count() ];
     148        for ( nv::uint16 bi = 0; bi < bones->get_count(); ++bi )
     149        {
     150                const mesh_node_data* bone = bones->get_node(bi);
     151                bone_names[ bone->name ] = bi;
     152                m_offsets[bi] = bone->transform;
     153        }
     154
     155        for ( uint32 n = 0; n < m_node_data->get_count(); ++n )
     156        {
     157                const mesh_node_data* node = m_node_data->get_node(n);
     158                sint16 bone_id = -1;
     159
     160                auto bi = bone_names.find( node->name );
     161                if ( bi != bone_names.end() )
     162                {
     163                        bone_id = bi->second;
     164                }
     165                m_bone_ids[n] = bone_id;
     166        }
     167        m_prepared = true;
     168}
     169
     170void nv::skeletal_animation_entry_gpu::animate_rec( mat4* data, float time, uint32 node_id, const mat4& parent_mat ) const
     171{
     172        // TODO: fix transforms, which are now embedded,
     173        //       see note in assimp_loader.cc:load_node
     174        const mesh_node_data* node = m_node_data->get_node( node_id );
     175        mat4 node_mat( node->transform );
     176
     177        if ( node->data )
     178        {
     179                node_mat = node->data->get_matrix( time );
     180        }
     181
     182        mat4 global_mat = parent_mat * node_mat;
     183
     184        sint16 bone_id = m_bone_ids[ node_id ];
     185        if ( bone_id >= 0 )
     186        {
     187                data[ bone_id ] = global_mat * m_offsets[ bone_id ];
     188        }
     189
     190        for ( auto child : m_children[ node_id ] )
     191        {
     192                animate_rec( data, time, child, global_mat );
     193        }
     194}
     195
     196nv::skeletal_animation_entry_gpu::~skeletal_animation_entry_gpu()
     197{
     198        delete[] m_offsets;
     199        delete[] m_children;
     200        delete[] m_bone_ids;
     201}
     202
     203nv::skeletal_mesh_gpu::skeletal_mesh_gpu( device* a_device, const mesh_data* a_mesh, const mesh_nodes_data* a_bone_data )
     204        : animated_mesh(), m_bone_data( a_bone_data ), m_transform( nullptr )
     205{
     206        m_va          = a_device->create_vertex_array( a_mesh, nv::STATIC_DRAW );
     207        m_index_count = a_mesh->get_count();
     208        if ( m_bone_data )
     209        {
     210                m_transform = new mat4[ m_bone_data->get_count() ];
     211        }
    70212}
    71213
    72214void nv::skeletal_mesh_gpu::run_animation( animation_entry* a_anim )
    73215{
    74         if ( m_primary && a_anim != nullptr )
     216        if ( m_bone_data && a_anim != nullptr )
    75217        {
    76218                skeletal_animation_entry_gpu * anim = (skeletal_animation_entry_gpu*)(a_anim);
    77                 m_transform.resize( m_model->get_bone_count() );
    78                 anim->prepare( m_model );
     219                anim->prepare( m_bone_data );
    79220                update_animation( a_anim, 0 );
    80221        }
     
    83224void nv::skeletal_mesh_gpu::update_animation( animation_entry* a_anim, uint32 a_anim_time )
    84225{
    85         if ( m_primary && a_anim )
     226        if ( m_bone_data && a_anim )
    86227        {
    87228                skeletal_animation_entry_gpu * anim = (skeletal_animation_entry_gpu*)a_anim;
    88                 anim->update_skeleton( m_transform.data(), a_anim_time );
     229                anim->update_skeleton( m_transform, a_anim_time );
    89230        }
    90231}
     
    92233void nv::skeletal_mesh_gpu::update( program* a_program ) const
    93234{
    94         if (m_primary)
    95                 a_program->set_uniform_array( "nv_m_bones", m_transform );
    96 }
     235        if ( m_bone_data )
     236                a_program->set_uniform_array( "nv_m_bones", m_transform, m_bone_data->get_count() );
     237}
     238
     239nv::transform nv::skeletal_mesh_gpu::get_node_transform( uint32 node_id ) const
     240{
     241        return transform( m_transform[ node_id ] );
     242}
     243
     244nv::mat4 nv::skeletal_mesh_gpu::get_node_matrix( uint32 node_id ) const
     245{
     246        return m_transform[ node_id ];
     247}
Note: See TracChangeset for help on using the changeset viewer.