Index: trunk/src/formats/assimp_loader.cc
===================================================================
--- trunk/src/formats/assimp_loader.cc	(revision 424)
+++ trunk/src/formats/assimp_loader.cc	(revision 425)
@@ -57,6 +57,6 @@
 
 
-nv::assimp_loader::assimp_loader( const std::string& a_ext, uint32 a_assimp_flags /*= 0 */ )
-	: m_scene( nullptr ), m_mesh_count(0)
+nv::assimp_loader::assimp_loader( string_table* strings, const string_view& a_ext, uint32 a_assimp_flags /*= 0 */ )
+	: mesh_loader( strings ), m_scene( nullptr ), m_mesh_count(0)
 {
 	m_ext   = a_ext;
@@ -92,5 +92,5 @@
 	char* data  = new char[ size ];
 	source.read( data, size, 1 );
-	const aiScene* scene = aiImportFileFromMemory( data, size, m_assimp_flags, m_ext.c_str() );
+	const aiScene* scene = aiImportFileFromMemory( data, size, m_assimp_flags, m_ext.data() );
 
 	if( !scene)
@@ -125,5 +125,6 @@
 		desc.initialize< assimp_plain_vtx >();
 	data_channel_set_creator maccess( data );
-	maccess.set_name( mesh->mName.data );
+	const char* name = mesh->mName.data;
+	maccess.set_name( make_name( name ) );
 	uint8*  cdata   = maccess.add_channel( desc, mesh->mNumVertices ).raw_data();
 	uint16* indices = reinterpret_cast<uint16*>( maccess.add_channel< index_u16 >( mesh->mNumFaces * 3 ).raw_data() );
@@ -201,5 +202,6 @@
 		bones[m].data = data_channel_set_creator::create_set( 0 );
 		data_channel_set_creator access( bones[m].data );
-		access.set_name( hash_string< uint64 >( bone->mName.data ) );
+		const char* name = bone->mName.data;
+		access.set_name( make_name( name ) );
 		access.set_transform( offset );
 	}
@@ -334,6 +336,5 @@
 	mesh_node_data* bones = new mesh_node_data[ final_bones.size() ];
 	raw_copy( final_bones.begin(), final_bones.end(), bones );
-	int name_;
-	return new mesh_nodes_data( /*"bones"*/0, final_bones.size(), bones );
+	return new mesh_nodes_data( make_name( "bones" ), final_bones.size(), bones );
 }
 
@@ -356,6 +357,5 @@
 	load_node( index, data, root, 0, -1 );
 
-	int name;
-	return new mesh_nodes_data( /*anim->mName.data*/0, count, data, frame_rate, duration, flat );
+	return new mesh_nodes_data( make_name( static_cast<const char*>( anim->mName.data ) ), count, data, frame_rate, duration, flat );
 }
 
@@ -375,5 +375,5 @@
 	const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
 	const aiNode*  node  = reinterpret_cast<const aiNode*>( vnode );
-	std::string name( node->mName.data );
+	string_view name( static_cast< const char* >( node->mName.data ) );
 	const aiAnimation* anim  = scene->mAnimations[anim_id];
 	const aiNodeAnim*  anode = nullptr;
@@ -382,5 +382,5 @@
 	{
 		anode = anim->mChannels[i];
-		if ( std::string( anode->mNodeName.data ) == name ) break;
+		if ( string_view( static_cast< const char* >( anode->mNodeName.data ) ) == name ) break;
 		anode = nullptr;
 	}
@@ -394,5 +394,5 @@
 
 	data_channel_set_creator access( a_data.data );
-	access.set_name( hash_string< uint64 >( name.c_str() ) );
+	access.set_name( make_name( name ) );
 	access.set_parent_id( parent_id );
 	// This value is ignored by the create_transformed_keys, but needed by create_direct_keys!
@@ -468,5 +468,5 @@
 	{
 		const aiMesh* mesh = scene->mMeshes[ m ];
-		data_channel_set_creator( &meshes[m] ).set_name( mesh->mName.data );
+		data_channel_set_creator( &meshes[m] ).set_name( make_name( static_cast<const char*>( mesh->mName.data ) ) );
 		if ( mesh->mNumBones > 0 ) has_bones = true;
 		load_mesh_data(&meshes[m],m);
Index: trunk/src/formats/md2_loader.cc
===================================================================
--- trunk/src/formats/md2_loader.cc	(revision 424)
+++ trunk/src/formats/md2_loader.cc	(revision 425)
@@ -199,5 +199,6 @@
 static bool s_md2_normal_ready = false;
 
-md2_loader::md2_loader() : m_md2( nullptr )
+md2_loader::md2_loader( string_table* strings ) 
+	: mesh_loader( strings ), m_md2( nullptr )
 {
 	if ( !s_md2_normal_ready )
@@ -331,4 +332,6 @@
 	uint16* icp        = &maccess.add_channel< index_u16 >( m_new_indexes.size() ).data()->index;
 
+	maccess.set_name( make_name( "md2_mesh" ) );
+
 	uint32 index = 0;
 	while ( frame_count > 0 )
Index: trunk/src/formats/md3_loader.cc
===================================================================
--- trunk/src/formats/md3_loader.cc	(revision 424)
+++ trunk/src/formats/md3_loader.cc	(revision 425)
@@ -235,6 +235,6 @@
 static bool s_normal_ready = false;
 
-md3_loader::md3_loader( bool merge_all )
-	: m_merge_all( merge_all ), m_md3( nullptr )
+md3_loader::md3_loader( string_table* strings, bool merge_all )
+	: mesh_loader( strings ), m_merge_all( merge_all ), m_md3( nullptr )
 {
 	if ( !s_normal_ready )
@@ -353,5 +353,6 @@
 
 	data_channel_set_creator maccess( data );
-	maccess.set_name( reinterpret_cast<char*>( md3->header.name ) );
+	maccess.set_name( make_name( reinterpret_cast<char*>( md3->header.name ) ) );
+
 
 	vtx_md3_pn* vtx_pn = maccess.add_channel< vtx_md3_pn >( static_cast< uint32 >( num_verts * frame_count ) ).data();
@@ -426,9 +427,8 @@
 		nodes[i].data      = data_channel_set_creator::create_set( 1 );
 		data_channel_set_creator access( nodes[i].data );
-		access.set_name( hash_string< uint64 >( name.data() ) );
+		access.set_name( make_name( name ) );
 		load_tags( access.add_channel<md3_key>( uint32( md3->header.num_frames ) ).channel(), name );
 	}
-	int name_;
-	return new mesh_nodes_data( 0,/*"tags"*/ node_count, nodes );
+	return new mesh_nodes_data( m_strings ? m_strings->insert( "tags" ) : 0, node_count, nodes );
 }
 
@@ -442,5 +442,4 @@
 		data = data_channel_set_creator::create_set_array(1,3);
 		release_mesh_frame( &data[0], -1, -1 );
-		data_channel_set_creator( &data[0] ).set_name( reinterpret_cast< char* >( md3->header.name ) );
 	}
 	else
@@ -451,5 +450,5 @@
 		{
 			release_mesh_frame( &data[i], -1, i );
-			data_channel_set_creator( &data[i] ).set_name( reinterpret_cast< char* >( md3->surfaces[i].header.name ) );
+			data_channel_set_creator( &data[i] ).set_name( make_name( reinterpret_cast< char* >( md3->surfaces[i].header.name ) ) );
 		}
 	}
Index: trunk/src/formats/md5_loader.cc
===================================================================
--- trunk/src/formats/md5_loader.cc	(revision 424)
+++ trunk/src/formats/md5_loader.cc	(revision 425)
@@ -112,6 +112,5 @@
 			assert( m_nodes == nullptr );
 			nodes = new mesh_node_data[ num_joints ];
-			int name_; //"md5_bones"
-			m_nodes = new mesh_nodes_data( 0, num_joints, nodes );
+			m_nodes = new mesh_nodes_data( make_name( "md5_bones"), num_joints, nodes );
 			discard( sstream, "{" );
 			for ( size_t i = 0; i < m_nodes->get_count(); ++i )
@@ -133,5 +132,5 @@
 				access.set_parent_id( parent_id );
 				access.set_transform( transform( pos, orient ).inverse().extract() );
-				access.set_name( hash_string< uint64 >( name.c_str() ) );
+				access.set_name( make_name( name.c_str() ) );
 				next_line( sstream );
 			}
@@ -157,4 +156,5 @@
 					sstream >> shader;
 					remove_quotes( shader );
+					maccess.set_name( make_name( shader ) );
 					next_line( sstream );
 				}
@@ -243,6 +243,5 @@
 			assert( nodes == nullptr );
 			nodes = new mesh_node_data[ num_joints ];
-			int name_;
-			m_nodes = new mesh_nodes_data( 0/*"md5_animation"*/, num_joints, nodes, static_cast< nv::uint16 >( frame_rate ), static_cast< float >( num_frames ), true );
+			m_nodes = new mesh_nodes_data( make_name( "md5_animation" ), num_joints, nodes, static_cast< nv::uint16 >( frame_rate ), static_cast< float >( num_frames ), true );
 			joint_infos.resize( num_joints );
 
@@ -257,5 +256,5 @@
 				data_channel_set_creator access( nodes[i].data );
 				access.add_channel< md5_key_t >( num_frames );
-				access.set_name( hash_string< uint64 >( name.c_str() ) );
+				access.set_name( make_name( name.c_str() ) );
 				access.set_parent_id( parent_id );
 				next_line( sstream );
Index: trunk/src/formats/nmd_loader.cc
===================================================================
--- trunk/src/formats/nmd_loader.cc	(revision 424)
+++ trunk/src/formats/nmd_loader.cc	(revision 425)
@@ -47,5 +47,4 @@
 {
 	data_channel_set* result = m_meshes[ index ];
-//	if ( m_strings ) data_channel_set_creator( result ).set_name( m_strings->get( m_mesh_names[ index ] ) );
 	m_meshes[ index ] = nullptr;
 	return result;
@@ -68,13 +67,9 @@
 {
 	for ( auto mesh : m_meshes ) if ( mesh ) delete mesh;
-	if ( m_strings )   delete m_strings;
 	if ( m_node_data ) delete m_node_data;
 	m_meshes.clear();
-//	m_mesh_names.clear();
-//	m_node_names.clear();
 
 	m_node_data  = nullptr;
 	m_node_array = nullptr;
-	m_strings    = nullptr;
 }
 
@@ -92,7 +87,9 @@
 bool nv::nmd_loader::load_strings( stream& source )
 {
-	NV_ASSERT( m_strings == nullptr, "MULTIPLE STRING ENTRIES!" );
+	if ( !m_strings ) return true;
 	// TODO: load strings optionally
-	m_strings = new string_table( source );
+	string_table* strings = new string_table( source );
+	m_strings->insert( strings );
+	delete strings;
 	return true;
 }
@@ -110,22 +107,8 @@
 		skip_attributes( source, element_header.attributes );
 		NV_ASSERT( element_header.type == nmd_type::NODE, "NODE expected!" );
-//		m_node_names.push_back( element_header.name );
-		load_node( source, &m_node_array[i], element_header );
+		m_node_array[i].data = data_channel_set_creator::create_set( element_header.children );
+		load_channel_set( source, m_node_array[i].data, element_header );
 	}
 	m_node_data = new mesh_nodes_data( e.name, e.children, m_node_array, animation_header.frame_rate, animation_header.duration, animation_header.flat );
-	return true;
-}
-
-bool nv::nmd_loader::load_node( stream& source, mesh_node_data* data, const nmd_element_header& e )
-{
-	data->data = data_channel_set_creator::create_set( e.children );
-	if ( e.children > 0 )
-	{
-		load_channel_set( source, data->data, e );
-	}
-	data_channel_set_creator access( data->data );
-	access.set_name( e.name );
-	access.set_parent_id( e.parent_id );
-	access.set_transform( e.transform );
 	return true;
 }
@@ -148,4 +131,8 @@
 		load_channel( source, channel_set );
 	}
+	data_channel_set_creator access( channel_set );
+	access.set_name( e.name );
+	access.set_parent_id( e.parent_id );
+	access.set_transform( e.transform );
 	return true;
 }
@@ -155,12 +142,4 @@
 	if ( m_node_data )
 	{
-// 		if ( m_strings )
-// 		{
-// 			for ( uint32 i = 0; i < m_node_data->get_count(); ++i )
-// 			{
-// 				m_node_array[i].name = m_strings->get( m_node_names[i] );
-// 				m_node_array[i].name_hash = hash_string< uint64 >( m_strings->get( m_node_names[i] ) );
-// 			}
-// 		}
 		mesh_nodes_data* result = m_node_data;
 		m_node_data = nullptr;
@@ -203,5 +182,4 @@
 	nmd_element_header eheader;
 	eheader.type = nmd_type::NODE;
-	//		eheader.name     = strings->insert( node->name );
 	eheader.children   = static_cast<uint16>( chan_count );
 	eheader.size       = chan_size;
Index: trunk/src/formats/obj_loader.cc
===================================================================
--- trunk/src/formats/obj_loader.cc	(revision 424)
+++ trunk/src/formats/obj_loader.cc	(revision 425)
@@ -291,6 +291,6 @@
 };
 
-nv::obj_loader::obj_loader( bool normals /*= true*/, bool tangents /*= false */ )
-	: m_normals( normals ), m_tangents( tangents )
+nv::obj_loader::obj_loader( string_table* strings, bool normals /*= true*/, bool tangents /*= false */ )
+	: mesh_loader( strings ), m_normals( normals ), m_tangents( tangents )
 {
 	if ( normals )
@@ -327,5 +327,6 @@
 	
 		data_channel_set* result = data_channel_set_creator::create_set( 1 );
-		data_channel_set_creator raccess( result );// ( reader->name );
+		data_channel_set_creator raccess( result );
+		raccess.set_name( make_name( reader->name ) );
 		uint8* rdata = raccess.add_channel( m_descriptor, reader->size * 3 ).raw_data();
 
Index: trunk/src/io/string_table.cc
===================================================================
--- trunk/src/io/string_table.cc	(revision 424)
+++ trunk/src/io/string_table.cc	(revision 425)
@@ -13,5 +13,5 @@
 	m_map.reserve( entry_count );
 	indexer_type::value_type entry;
-	for ( uint32 i = 0; i < entry_count; )
+	for ( uint32 i = 0; i < entry_count; i++ )
 	{
 		in.read( &entry, sizeof( entry ), 1 );
