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
File:
1 edited

Legend:

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

    r285 r287  
    77#include "nv/formats/nmd_loader.hh"
    88#include "nv/io/std_stream.hh"
     9#include "nv/string.hh"
    910
    1011using namespace nv;
     
    2425                case nmd_type::MESH           : load_mesh( source, element_header ); break;
    2526                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;
     
    4747                mesh->add_channel( channel );
    4848        }
     49        m_mesh_names.push_back( e.name );
    4950        m_meshes.push_back( mesh );
    5051        return true;
     
    5455{
    5556        mesh_data* result = m_meshes[ index ];
     57        if ( m_strings ) result->set_name( m_strings->get( m_mesh_names[ index ] ) );
    5658        m_meshes[ index ] = nullptr;
    5759        return result;
     60}
     61
     62mesh_data_pack* nv::nmd_loader::release_mesh_data_pack()
     63{
     64        uint32 size = m_meshes.size();
     65        mesh_data* meshes = new mesh_data[ size ];
     66        for ( uint32 i = 0; i < size; ++i )
     67        {
     68                m_meshes[i]->move_to( meshes[i] );
     69                delete m_meshes[i];
     70        }
     71        m_meshes.clear();
     72        return new mesh_data_pack( size, meshes, release_mesh_nodes_data() );
    5873}
    5974
     
    6176{
    6277        for ( auto mesh : m_meshes ) if ( mesh ) delete mesh;
    63         if ( m_animation ) delete m_animation;
    6478        if ( m_strings )   delete m_strings;
    65         if ( m_bone_data ) delete m_bone_data;
     79        if ( m_node_data ) delete m_node_data;
    6680        m_meshes.clear();
    67         m_animation = nullptr;
    68         m_bone_data = nullptr;
    69         m_strings   = nullptr;
     81        m_mesh_names.clear();
     82        m_node_names.clear();
     83
     84        m_node_data  = nullptr;
     85        m_node_array = nullptr;
     86        m_strings    = nullptr;
    7087}
    7188
     
    8299}
    83100
    84 bool nv::nmd_loader::load_bones( stream& source, const nmd_element_header& e )
    85 {
    86         NV_ASSERT( m_bone_data == nullptr, "MULTIPLE BONE ENTRIES!" );
    87         m_bone_data = new nmd_bone_data;
    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 );
    91         return true;
    92 }
    93 
    94 nmd_animation* nv::nmd_loader::release_animation()
    95 {
    96         nmd_animation* result = m_animation;
    97         m_animation = nullptr;
    98         return result;
    99 }
    100 
    101 nmd_bone_data* nv::nmd_loader::release_bone_data()
    102 {
    103         nmd_bone_data* result = m_bone_data;
    104         m_bone_data = nullptr;
    105         return result;
    106 }
    107 
    108 string_table* nv::nmd_loader::release_string_table()
    109 {
    110         string_table* result = m_strings;
    111         m_strings = nullptr;
    112         return result;
    113 }
    114 
    115 
    116101bool nv::nmd_loader::load_animation( stream& source, const nmd_element_header& e )
    117102{
    118         NV_ASSERT( m_animation == nullptr, "MULTIPLE ANIMATION ENTRIES!" );
    119         nmd_animation_header header;
    120         source.read( &header, sizeof( header ), 1 );
    121         m_animation = new nmd_animation;
    122         m_animation->fps        = header.fps;
    123         m_animation->duration   = header.duration;
    124         m_animation->flat       = header.flat;
    125         m_animation->node_count = (uint16)e.children;
    126         m_animation->nodes      = new nmd_node[ e.children ];
     103        NV_ASSERT( m_node_data == nullptr, "MULTIPLE NODE ENTRIES!" );
     104        nmd_animation_header animation_header;
     105        source.read( &animation_header, sizeof( animation_header ), 1 );
     106        m_node_array = new mesh_node_data[ e.children ];
    127107        for ( uint32 i = 0; i < e.children; ++i )
    128108        {
    129109                nmd_element_header element_header;
    130110                source.read( &element_header, sizeof( element_header ), 1 );
    131                 NV_ASSERT( element_header.type == nmd_type::ANIMATION_NODE, "ANIMATION_NODE expected!" );
    132                 m_animation->nodes[i].name          = element_header.name;
    133 
     111                NV_ASSERT( element_header.type == nmd_type::NODE, "NODE expected!" );
     112                m_node_names.push_back( element_header.name );
    134113                uint16 ch_count = element_header.children;
    135114
    136                 nmd_animation_node_header node_header;
     115                nmd_node_header node_header;
    137116                source.read( &node_header, sizeof( node_header ), 1 );
    138                 m_animation->nodes[i].parent_id     = node_header.parent_id;
    139                 m_animation->nodes[i].transform     = node_header.transform;
    140                 m_animation->nodes[i].data          = nullptr;
     117                m_node_array[i].parent_id     = node_header.parent_id;
     118                m_node_array[i].transform     = node_header.transform;
     119                m_node_array[i].data          = nullptr;
    141120                if ( ch_count > 0 )
    142121                {
    143122                        key_data* kdata = new key_data;
    144                         m_animation->nodes[i].data = kdata;
     123                        m_node_array[i].data = kdata;
    145124                        for ( uint32 c = 0; c < ch_count; ++c )
    146125                        {
    147126                                source.read( &element_header, sizeof( element_header ), 1 );
    148                                 NV_ASSERT( element_header.type == nmd_type::ANIMATION_CHANNEL, "ANIMATION_CHANNEL expected!" );
    149                                 nv::nmd_animation_channel_header cheader;
     127                                NV_ASSERT( element_header.type == nmd_type::KEY_CHANNEL, "CHANNEL expected!" );
     128                                nv::nmd_key_channel_header cheader;
    150129                                source.read( &cheader, sizeof( cheader ), 1 );
    151130                                key_raw_channel* channel = key_raw_channel::create( cheader.format, cheader.count );
     
    155134                }
    156135        }
     136        m_node_data = new mesh_nodes_data( "animation", e.children, m_node_array, animation_header.frame_rate, animation_header.duration, animation_header.flat );
    157137        return true;
    158138}
    159139
     140mesh_nodes_data* nv::nmd_loader::release_mesh_nodes_data()
     141{
     142        if ( m_node_data )
     143        {
     144                if ( m_strings )
     145                {
     146                        for ( uint32 i = 0; i < m_node_data->get_count(); ++i )
     147                        {
     148                                m_node_array[i].name = m_strings->get( m_node_names[i] );
     149                        }
     150                }
     151                mesh_nodes_data* result = m_node_data;
     152                m_node_data = nullptr;
     153                m_node_array = nullptr;
     154                return result;
     155        }
     156        return nullptr;
     157}
    160158
    161159// TEMPORARY
    162 nv::nmd_temp_animation::nmd_temp_animation( nmd_loader* loader )
    163 {
    164         m_animation = loader->release_animation();
    165         m_strings   = loader->release_string_table();
    166160
    167         for ( uint32 n = 0; n < m_animation->node_count; ++n )
    168         {
    169                 nmd_node& node = m_animation->nodes[n];
    170                 m_data.push_back( node.data );
    171                 node.data = nullptr;
    172         }
    173 
    174         if ( !m_animation->flat )
    175         {
    176                 m_children.resize( m_animation->node_count );
    177                 for ( nv::uint32 n = 0; n < m_animation->node_count; ++n )
    178                 {
    179                         const nmd_node& node = m_animation->nodes[n];
    180                         if ( node.parent_id != -1 )
    181                         {
    182                                 m_children[ node.parent_id ].push_back( n );
    183                         }
    184                 }
    185         }
    186 
    187         m_bone_ids.resize( m_animation->node_count );
    188 }
    189 
    190 nv::nmd_temp_animation::~nmd_temp_animation()
    191 {
    192         for ( auto node : m_data ) delete node;
    193         delete m_animation;
    194         delete m_strings;
    195 }
    196 
    197 void nv::nmd_temp_animation::prepare( const nmd_temp_model* model )
    198 {
    199         m_offsets = model->m_bone_offsets.data();
    200         for ( uint32 n = 0; n < m_animation->node_count; ++n )
    201         {
    202                 const nmd_node& node = m_animation->nodes[n];
    203                 sint16 bone_id = -1;
    204 
    205                 auto bi = model->m_bone_names.find( m_strings->get( node.name ) );
    206                 if ( bi != model->m_bone_names.end() )
    207                 {
    208                         bone_id = bi->second;
    209                 }
    210                 m_bone_ids[n] = bone_id;
    211         }
    212 }
    213 
    214 void nv::nmd_temp_animation::animate( mat4* data, uint32 time )
    215 {
    216         float tick_time = ( time / 1000.0f ) * m_animation->fps;
    217         float anim_time = fmodf( tick_time, m_animation->duration );
    218 
    219         if ( !m_animation->flat )
    220         {
    221                 animate_rec( data, anim_time, 0, mat4() );
    222                 return;
    223         }
    224 
    225         for ( uint32 n = 0; n < m_animation->node_count; ++n )
    226                 if ( m_bone_ids[n] >= 0 )
    227                 {
    228                         const nmd_node* node = &m_animation->nodes[ n ];
    229                         nv::mat4 node_mat( node->transform );
    230 
    231                         if ( m_data[n] )
    232                         {
    233                                 node_mat = m_data[n]->get_matrix( anim_time );
    234                         }
    235 
    236                         sint16 bone_id = m_bone_ids[n];
    237                         data[ bone_id ] = node_mat * m_offsets[ bone_id ];
    238                 }
    239 
    240 }
    241 
    242 void nv::nmd_temp_animation::animate_rec( mat4* data, float time, uint32 node_id, const mat4& parent_mat )
    243 {
    244         // TODO: fix transforms, which are now embedded,
    245         //       see note in assimp_loader.cc:load_node
    246         const nmd_node* node = &m_animation->nodes[ node_id ];
    247         mat4 node_mat( node->transform );
    248 
    249         if ( m_data[ node_id ] )
    250         {
    251                 node_mat = m_data[ node_id ]->get_matrix( time );
    252         }
    253 
    254         mat4 global_mat = parent_mat * node_mat;
    255 
    256         sint16 bone_id = m_bone_ids[ node_id ];
    257         if ( bone_id >= 0 )
    258         {
    259                 data[ bone_id ] = global_mat * m_offsets[ bone_id ];
    260         }
    261 
    262         for ( auto child : m_children[ node_id ] )
    263         {
    264                 animate_rec( data, time, child, global_mat );
    265         }
    266 }
    267 
    268 nv::nmd_temp_model::nmd_temp_model( nmd_loader* loader )
     161nv::nmd_temp_model_data::nmd_temp_model_data( nmd_loader* loader )
    269162{
    270163        for ( unsigned m = 0; m < loader->get_mesh_count(); ++m )
     
    272165                m_mesh_data.push_back(loader->release_mesh_data(m));
    273166        }
    274         nmd_bone_data* bone_data = loader->release_bone_data();
    275         string_table*  strings   = loader->release_string_table();
    276 
    277         for ( nv::uint16 bi = 0; bi < bone_data->count; ++bi )
    278         {
    279                 m_bone_names[ strings->get( bone_data->bones[bi].name ) ] = bi;
    280                 m_bone_offsets.push_back( bone_data->bones[bi].offset );
    281         }
    282 
    283         delete bone_data;
    284         delete strings;
     167        m_node_data = loader->release_mesh_nodes_data();
    285168}
    286169
    287 nv::nmd_temp_model::~nmd_temp_model()
     170nv::nmd_temp_model_data::~nmd_temp_model_data()
    288171{
    289172        for ( unsigned m = 0; m < m_mesh_data.size(); ++m )
     
    291174                delete m_mesh_data[m];
    292175        }
     176        delete m_node_data;
    293177}
Note: See TracChangeset for help on using the changeset viewer.