Index: trunk/src/formats/assimp_loader.cc
===================================================================
--- trunk/src/formats/assimp_loader.cc	(revision 284)
+++ trunk/src/formats/assimp_loader.cc	(revision 285)
@@ -367,5 +367,5 @@
 	if (this_id == 0)
 		a_data.transform = mat4();
-	a_data.channel_count = 0;
+	a_data.data = nullptr;
 
 	if (anode) 
@@ -394,7 +394,8 @@
 	size_t max_keys = glm::max( node->mNumPositionKeys, node->mNumRotationKeys );
 
-	data->channel_count = 1;
-	data->channels[0] = key_raw_channel::create<assimp_key_tr>( max_keys );
-	assimp_key_tr* channel = ((assimp_key_tr*)(data->channels[0]->data));
+	key_raw_channel* raw_channel = key_raw_channel::create<assimp_key_tr>( max_keys );
+	data->data = new key_data;
+	data->data->add_channel( raw_channel );
+	assimp_key_tr* channel = ((assimp_key_tr*)(raw_channel->data));
 
 	for ( unsigned n = 0; n < max_keys; ++n )
@@ -406,10 +407,10 @@
 		// TODO: only do the calculation when a rotate transform is present!
 		nv::transform ptr;
-		if ( parent )
-		{
-			key_raw_channel* pchannel = parent->channels[0];
-			if ( parent->channels[0] && parent->channels[0]->count > 0 )
-			{
-				ptr = ((assimp_key_tr*)pchannel->data)[ glm::min( n, parent->channels[0]->count-1 ) ].tform;
+		if ( parent && parent->data )
+		{
+			const key_raw_channel* pchannel = parent->data->get_channel(0);
+			if ( pchannel && pchannel->count > 0 )
+			{
+				ptr = ((assimp_key_tr*)pchannel->data)[ glm::min( n, pchannel->count-1 ) ].tform;
 			}
 		}
@@ -422,5 +423,4 @@
 void nv::assimp_loader::create_direct_keys( assimp_animated_node_data* data, const void* vnode )
 {
-	data->channel_count = 0;
 	const aiNodeAnim* node = (const aiNodeAnim*)vnode;
 	if ( node->mNumPositionKeys == 0 && node->mNumRotationKeys == 0 && node->mNumScalingKeys == 0 )
@@ -429,11 +429,14 @@
 	}
 
-	data->channel_count = 3;
-	data->channels[0] = key_raw_channel::create<assimp_key_p>( node->mNumPositionKeys );
-	data->channels[1] = key_raw_channel::create<assimp_key_r>( node->mNumRotationKeys );
-	data->channels[2] = key_raw_channel::create<assimp_key_s>( node->mNumScalingKeys );
-	assimp_key_p* pchannel = ((assimp_key_p*)(data->channels[0]->data));
-	assimp_key_r* rchannel = ((assimp_key_r*)(data->channels[1]->data));
-	assimp_key_s* schannel = ((assimp_key_s*)(data->channels[2]->data));
+	data->data = new key_data;
+	key_raw_channel* raw_pchannel = key_raw_channel::create<assimp_key_p>( node->mNumPositionKeys );
+	key_raw_channel* raw_rchannel = key_raw_channel::create<assimp_key_r>( node->mNumRotationKeys );
+	key_raw_channel* raw_schannel = key_raw_channel::create<assimp_key_s>( node->mNumScalingKeys );
+	data->data->add_channel( raw_pchannel );
+	data->data->add_channel( raw_rchannel );
+	data->data->add_channel( raw_schannel );
+	assimp_key_p* pchannel = ((assimp_key_p*)(raw_pchannel->data));
+	assimp_key_r* rchannel = ((assimp_key_r*)(raw_rchannel->data));
+	assimp_key_s* schannel = ((assimp_key_s*)(raw_schannel->data));
 
 	for ( unsigned np = 0; np < node->mNumPositionKeys; ++np )
Index: trunk/src/formats/md3_loader.cc
===================================================================
--- trunk/src/formats/md3_loader.cc	(revision 284)
+++ trunk/src/formats/md3_loader.cc	(revision 285)
@@ -407,12 +407,37 @@
 	for ( sint32 i = 0; i < md3->header.num_tags; ++i )
 	{
-		const md3_tag_t& rtag = md3->tags[i + md3->header.num_tags];
+		const md3_tag_t& rtag = md3->tags[i];
 		std::string name( (char*)(rtag.name) );
-		nv::key_raw_channel* keys = load_tags( name );
-		result->insert( name, keys );
+
+		key_data* data = new key_data;
+		data->add_channel( load_tags( name ) );
+		result->insert( name, data );
 	}
 	return result;
 }
 
+mesh_node_data* nv::md3_loader::release_mesh_node_data( size_t index )
+{
+	md3_t* md3 = (md3_t*)m_md3;
+	const md3_tag_t& rtag = md3->tags[index];
+	std::string name( (char*)(rtag.name) );
+
+	mesh_node_data* result = new mesh_node_data;
+	result->transform = mat4();
+	result->name      = name;
+	result->parent_id = -1;
+	result->target_id = -1;
+	result->data = new key_data;
+	
+	key_raw_channel* keys = load_tags( name );
+	result->data->add_channel( keys );
+	return result;
+}
+
+size_t nv::md3_loader::get_node_count() const
+{
+	return ((md3_t*)m_md3)->header.num_tags;
+}
+
 size_t md3_loader::get_max_frames() const
 {
Index: trunk/src/formats/nmd_loader.cc
===================================================================
--- trunk/src/formats/nmd_loader.cc	(revision 284)
+++ trunk/src/formats/nmd_loader.cc	(revision 285)
@@ -138,9 +138,9 @@
 		m_animation->nodes[i].parent_id     = node_header.parent_id;
 		m_animation->nodes[i].transform     = node_header.transform;
-		m_animation->nodes[i].channel_count = ch_count;
-		m_animation->nodes[i].channels      = nullptr;
+		m_animation->nodes[i].data          = nullptr;
 		if ( ch_count > 0 )
 		{
-			m_animation->nodes[i].channels      = new key_raw_channel* [ch_count];
+			key_data* kdata = new key_data;
+			m_animation->nodes[i].data = kdata;
 			for ( uint32 c = 0; c < ch_count; ++c )
 			{
@@ -151,5 +151,5 @@
 				key_raw_channel* channel = key_raw_channel::create( cheader.format, cheader.count );
 				source.read( channel->data, channel->desc.size, channel->count );
-				m_animation->nodes[i].channels[c] = channel;
+				kdata->add_channel( channel );
 			}
 		}
@@ -168,16 +168,6 @@
 	{
 		nmd_node& node = m_animation->nodes[n];
-		key_animation_data* keys = nullptr;
-		if ( node.channel_count > 1 )
-		{
-			keys = new nv::key_vectors_prs( node.channels[0], node.channels[1], node.channels[2] );
-		}
-		else if ( node.channel_count == 1 )
-		{
-			keys      =  new nv::transform_vector( node.channels[0] );
-			node.channels[0] = nullptr;
-			node.channel_count = 0;
-		}
-		m_data.push_back( keys );
+		m_data.push_back( node.data );
+		node.data = nullptr;
 	}
 
@@ -239,5 +229,5 @@
 			nv::mat4 node_mat( node->transform );
 
-			if ( m_data[n] && !m_data[n]->empty() )
+			if ( m_data[n] )
 			{
 				node_mat = m_data[n]->get_matrix( anim_time );
@@ -257,5 +247,5 @@
 	mat4 node_mat( node->transform );
 
-	if ( m_data[ node_id ] && !m_data[ node_id ]->empty() )
+	if ( m_data[ node_id ] )
 	{
 		node_mat = m_data[ node_id ]->get_matrix( time );
