Index: trunk/src/formats/assimp_loader.cc
===================================================================
--- trunk/src/formats/assimp_loader.cc	(revision 291)
+++ trunk/src/formats/assimp_loader.cc	(revision 292)
@@ -63,8 +63,8 @@
 bool nv::assimp_loader::load( stream& source )
 {
+	load_assimp_library();
 	if ( m_scene != nullptr ) aiReleaseImport( (const aiScene*)m_scene );
 	m_scene = nullptr;
 	m_mesh_count = 0;
-	load_assimp_library();
 	NV_LOG( nv::LOG_NOTICE, "AssImp loading file..." );
 	int size = (int)source.size();
Index: trunk/src/formats/nmd_loader.cc
===================================================================
--- trunk/src/formats/nmd_loader.cc	(revision 291)
+++ trunk/src/formats/nmd_loader.cc	(revision 292)
@@ -157,2 +157,142 @@
 }
 
+// ----------------------------------------------------------------
+// nmd format dump
+// HACK : TEMPORARY - will go to it's own file, probably nmd_io
+static void nmd_dump_mesh( const mesh_data* mesh, stream& stream_out )
+{
+	const std::vector< mesh_raw_channel* >& data  = mesh->get_raw_channels();
+
+	uint32 size = sizeof( nmd_element_header );
+	for ( auto chan : data )
+	{
+		size += sizeof( nmd_element_header ) + sizeof( nmd_stream_header );
+		size += chan->size();
+	}
+
+	nmd_element_header eheader;
+	eheader.type     = nmd_type::MESH;
+	eheader.name     = 0;
+	eheader.children = (uint16)data.size();
+	eheader.size     = size;
+	stream_out.write( &eheader, sizeof( eheader ), 1 );
+
+	for ( auto chan : data )
+	{
+		nmd_element_header cheader;
+		eheader.name     = 0;
+		cheader.type     = nmd_type::STREAM;
+		cheader.children = 0;
+		cheader.size     = chan->size() + sizeof( nmd_stream_header );
+		stream_out.write( &cheader, sizeof( cheader ), 1 );
+
+		nmd_stream_header sheader;
+		sheader.format = chan->desc;
+		sheader.count  = chan->count;
+		stream_out.write( &sheader, sizeof( sheader ), 1 );
+		stream_out.write( chan->data, chan->desc.size, chan->count );
+	}
+}
+
+static void nmd_dump_nodes_data( const mesh_nodes_data* nodes, stream& stream_out, string_table_creator* strings )
+{
+	uint32 total = sizeof( nmd_animation_header );
+	for ( uint32 i = 0; i < nodes->get_count(); ++i )
+	{
+		const mesh_node_data* node = nodes->get_node(i);
+		total += sizeof( nmd_element_header ) + sizeof( nmd_node_header );
+		if ( node->data )
+			for ( uint32 c = 0; c < node->data->get_channel_count(); ++c )
+			{
+				total += sizeof( nmd_element_header ) + sizeof( nmd_key_channel_header );
+				total += node->data->get_channel(c)->size();
+			}
+	}
+
+	nmd_element_header header;
+	header.name     = 0;
+	header.type     = nmd_type::ANIMATION;
+	header.children = (uint16)nodes->get_count();
+	header.size     = total;
+	stream_out.write( &header, sizeof( header ), 1 );
+
+	nmd_animation_header aheader;
+	aheader.frame_rate  = nodes->get_frame_rate();
+	aheader.duration    = nodes->get_duration();
+	aheader.flat        = nodes->is_flat();
+	stream_out.write( &aheader, sizeof( aheader ), 1 );
+
+	for ( uint32 i = 0; i < nodes->get_count(); ++i )
+	{
+		const mesh_node_data* node = nodes->get_node(i);
+		uint32 chan_size  = 0;
+		uint32 chan_count = ( node->data ? node->data->get_channel_count() : 0 );
+		for ( uint32 c = 0; c < chan_count; ++c )
+		{
+			chan_size += sizeof( nmd_element_header ) + sizeof( nv::nmd_key_channel_header );
+			chan_size += node->data->get_channel(c)->size();
+		}
+
+		nmd_element_header eheader;
+		eheader.type     = nmd_type::NODE;
+		eheader.name     = strings->insert( node->name );
+		eheader.children = (uint16)chan_count;
+		eheader.size     = sizeof( nmd_node_header ) + chan_size;
+		stream_out.write( &eheader, sizeof( eheader ), 1 );
+
+		nmd_node_header nheader;
+		nheader.parent_id = (uint16)node->parent_id;
+		nheader.transform = node->transform;
+		stream_out.write( &nheader, sizeof( nheader ), 1 );
+
+		for ( uint32 c = 0; c < chan_count; ++c )
+		{
+			const key_raw_channel* channel = node->data->get_channel(c);
+
+			eheader.type     = nmd_type::KEY_CHANNEL;
+			eheader.children = 0;
+			eheader.size     = sizeof( nmd_key_channel_header ) + channel->size();
+			stream_out.write( &eheader, sizeof( eheader ), 1 );
+
+			nmd_key_channel_header cheader;
+			cheader.format    = channel->desc;
+			cheader.count     = channel->count;
+			stream_out.write( &cheader, sizeof( cheader ), 1 );
+			stream_out.write( channel->data, channel->desc.size, channel->count );
+		}
+	}
+}
+
+void nv::nmd_dump( const mesh_data_pack* model, stream& stream_out )
+{
+	string_table_creator strings;
+	{
+		nmd_header header;
+		header.id       = four_cc<'n','m','f','1'>::value;
+		header.elements = 1; // +1 string array
+		header.elements += model->get_count();
+		if ( model->get_nodes() && model->get_nodes()->get_count() > 0 ) 
+			header.elements += 1;//  +1 bone array
+		header.version  = 1;
+		stream_out.write( &header, sizeof( header ), 1 );
+	}
+
+	for ( uint32 i = 0; i < model->get_count(); ++i )
+	{
+		const mesh_data* mesh = model->get_mesh(i);
+		nmd_dump_mesh( mesh, stream_out );
+	}
+
+	if ( model->get_nodes() && model->get_nodes()->get_count() > 0 )
+	{
+		nmd_dump_nodes_data( model->get_nodes(), stream_out, &strings );
+	}
+
+	nmd_element_header sheader;
+	sheader.type     = nv::nmd_type::STRING_TABLE;
+	sheader.name     = 0;
+	sheader.size     = strings.dump_size();
+	sheader.children = 0;
+	stream_out.write( &sheader, sizeof( sheader ), 1 );
+	strings.dump( &stream_out );
+}
