Index: trunk/src/formats/assimp_loader.cc
===================================================================
--- trunk/src/formats/assimp_loader.cc	(revision 415)
+++ trunk/src/formats/assimp_loader.cc	(revision 416)
@@ -6,4 +6,6 @@
 
 #include "nv/formats/assimp_loader.hh"
+
+#include "nv/interface/data_channel_access.hh"
 #include "nv/stl/unordered_map.hh"
 #include "nv/lib/assimp.hh"
@@ -103,16 +105,15 @@
 }
 
-mesh_data* nv::assimp_loader::release_mesh_data( size_t index /*= 0 */ )
+data_channel_set* nv::assimp_loader::release_mesh_data( size_t index /*= 0 */ )
 {
 	if ( index >= m_mesh_count ) return nullptr;
-	mesh_data* result = new mesh_data;
+	data_channel_set* result = data_channel_set_creator::create( 2 );
 	load_mesh_data( result, index );
 	return result;
 }
-void nv::assimp_loader::load_mesh_data( mesh_data* data, size_t index )
+void nv::assimp_loader::load_mesh_data( data_channel_set* data, size_t index )
 {
 	const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
 	const aiMesh*  mesh  = scene->mMeshes[ index ];
-	data->set_name( mesh->mName.data );
 
 	bool skinned = mesh->mNumBones > 0;
@@ -180,6 +181,9 @@
 		}
 	}
-	data->add_channel( channel.release() );
-	data->add_channel( ichannel.release() );
+
+	data_channel_set_creator maccess( data );
+	maccess.set_name( mesh->mName.data );
+	maccess.add_channel( channel.release() );
+	maccess.add_channel( ichannel.release() );
 }
 
@@ -283,5 +287,5 @@
 }
 
-mesh_nodes_data* nv::assimp_loader::release_merged_bones( mesh_data* meshes )
+mesh_nodes_data* nv::assimp_loader::release_merged_bones( data_channel_set* meshes )
 {
 	const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
@@ -317,5 +321,5 @@
 			if ( m > 0 && bones.size() > 0 )
 			{
-				data_channel_creator< assimp_skinned_vtx > channel( meshes[m].get_raw_channels()[0] );
+				data_channel_creator< assimp_skinned_vtx > channel( const_cast< raw_data_channel* >( meshes[m].get_channel(0) ) );
 				for ( unsigned v = 0; v < channel.size(); ++v )
 				{
@@ -456,7 +460,7 @@
 // 		}
 // 	}
-	data->data->add_channel( pchannel_creator.release() );
-	data->data->add_channel( rchannel_creator.release() );
-//	data->data->add_channel( schannel_creator.release() );
+	data->data->add_key_channel( pchannel_creator.release() );
+	data->data->add_key_channel( rchannel_creator.release() );
+//	data->data->add_key_channel( schannel_creator.release() );
 }
 
@@ -466,9 +470,9 @@
 	const aiScene* scene = reinterpret_cast<const aiScene*>( m_scene );
 	bool has_bones = false;
-	mesh_data* meshes = new mesh_data[ m_mesh_count ];
+	data_channel_set* meshes = data_channel_set_creator::create_array( m_mesh_count, 2 );
 	for ( size_t m = 0; m < m_mesh_count; ++m )
 	{
 		const aiMesh* mesh = scene->mMeshes[ m ];
-		meshes[m].set_name( mesh->mName.data );
+		data_channel_set_creator( &meshes[m] ).set_name( 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 415)
+++ trunk/src/formats/md2_loader.cc	(revision 416)
@@ -8,4 +8,6 @@
 
 #include "nv/core/logging.hh"
+#include "nv/interface/data_channel_access.hh"
+
 #include <cstring>
 
@@ -309,12 +311,12 @@
 
 
-mesh_data* nv::md2_loader::release_mesh_data( size_t )
-{
-	mesh_data* data = new mesh_data( "md2_mesh" );
+data_channel_set* nv::md2_loader::release_mesh_data( size_t )
+{
+	data_channel_set* data = data_channel_set_creator::create( 3 );
 	release_mesh_frame( data, -1 );
 	return data;
 }
 
-void nv::md2_loader::release_mesh_frame( mesh_data* data, sint32 frame )
+void nv::md2_loader::release_mesh_frame( data_channel_set* data, sint32 frame )
 {
 	md2_t* md2 = reinterpret_cast< md2_t* >( m_md2 );
@@ -364,12 +366,14 @@
 	}
 
-	data->add_channel( mc_pn.release() );
-	data->add_channel( mc_t.release() );
-	data->add_channel( ic.release() );
+	data_channel_set_creator maccess( data );
+
+	maccess.add_channel( mc_pn.release() );
+	maccess.add_channel( mc_t.release() );
+	maccess.add_channel( ic.release() );
 }
 
 mesh_data_pack* nv::md2_loader::release_mesh_data_pack()
 {
-	mesh_data* data = new mesh_data[1];
+	data_channel_set* data = data_channel_set_creator::create_array( 1, 3 );
 	release_mesh_frame( &data[0], -1 );
 	return new mesh_data_pack( 1, data );
Index: trunk/src/formats/md3_loader.cc
===================================================================
--- trunk/src/formats/md3_loader.cc	(revision 415)
+++ trunk/src/formats/md3_loader.cc	(revision 416)
@@ -8,4 +8,5 @@
 
 #include "nv/core/logging.hh"
+#include "nv/interface/data_channel_access.hh"
 
 using namespace nv;
@@ -322,12 +323,12 @@
 };
 
-mesh_data* nv::md3_loader::release_mesh_data( nv::size_t index )
-{
-	mesh_data* data = new mesh_data;
+data_channel_set* nv::md3_loader::release_mesh_data( nv::size_t index )
+{
+	data_channel_set* data = data_channel_set_creator::create(3);
 	release_mesh_frame( data, -1, static_cast< sint32 >( index ) );
 	return data;
 }
 
-void nv::md3_loader::release_mesh_frame( mesh_data* data, sint32 frame, sint32 surface )
+void nv::md3_loader::release_mesh_frame( data_channel_set* data, sint32 frame, sint32 surface )
 {
 	md3_t* md3 = reinterpret_cast< md3_t* >( m_md3 );
@@ -412,8 +413,9 @@
 	}
 
-	data->set_name( reinterpret_cast< char* >( md3->header.name ) );
-	data->add_channel( mc_pn.release() );
-	data->add_channel( mc_t.release() );
-	data->add_channel( ic.release() );
+	data_channel_set_creator maccess( data );
+	maccess.set_name( reinterpret_cast<char*>( md3->header.name ) );
+	maccess.add_channel( mc_pn.release() );
+	maccess.add_channel( mc_t.release() );
+	maccess.add_channel( ic.release() );
 }
 
@@ -436,5 +438,5 @@
 	
 		raw_data_channel* keys = load_tags( name );
-		nodes[i].data->add_channel( keys );
+		nodes[i].data->add_key_channel( keys );
 	}
 	return new mesh_nodes_data( "tags", node_count, nodes );
@@ -445,19 +447,19 @@
 	md3_t* md3 = reinterpret_cast<md3_t*>( m_md3 );
 	int count = 1;
-	mesh_data* data = nullptr;
+	data_channel_set* data = nullptr;
 	if ( m_merge_all )
 	{
-		data = new mesh_data[1];
+		data = data_channel_set_creator::create_array(1,3);
 		release_mesh_frame( &data[0], -1, -1 );
-		data[0].set_name( reinterpret_cast< char* >( md3->header.name ) );
+		data_channel_set_creator( &data[0] ).set_name( reinterpret_cast< char* >( md3->header.name ) );
 	}
 	else
 	{
 		count = md3->header.num_surfaces;
-		data = new mesh_data[ count ];
+		data = data_channel_set_creator::create_array( count, 3 );
 		for ( int i = 0; i < count; ++i )
 		{
 			release_mesh_frame( &data[i], -1, i );
-			data[i].set_name( reinterpret_cast< char* >( md3->surfaces[i].header.name ) );
+			data_channel_set_creator( &data[i] ).set_name( reinterpret_cast< char* >( md3->surfaces[i].header.name ) );
 		}
 	}
Index: trunk/src/formats/md5_loader.cc
===================================================================
--- trunk/src/formats/md5_loader.cc	(revision 415)
+++ trunk/src/formats/md5_loader.cc	(revision 416)
@@ -10,4 +10,5 @@
 #include "nv/stl/vector.hh"
 #include "nv/io/std_stream.hh"
+#include "nv/interface/data_channel_access.hh"
 
 #include <stdio.h>  // sscanf
@@ -136,5 +137,5 @@
 		{
 			assert( m_type == MESH );
-			mesh_data* mesh = new mesh_data("md5_mesh");
+			data_channel_set_creator mesh;
 
 			uint32 num_verts   = 0;
@@ -163,9 +164,9 @@
 						data_channel_creator<md5_vtx_pntiw> ch_pntiw( num_verts );
 						tdata = ch_t.data();
-						mesh->add_channel( ch_pnt.release() );
-						mesh->add_channel( ch_t.release() );
+						mesh.add_channel( ch_pnt.release() );
+						mesh.add_channel( ch_t.release() );
 						// TODO: hack to prevent rendering
 						//ch_pntiw->m_count = 0;
-						mesh->add_channel( ch_pntiw.release() );
+						mesh.add_channel( ch_pntiw.release() );
 					}
 					weight_info.resize( num_verts );
@@ -210,5 +211,5 @@
 					}              
 
-					mesh->add_channel( ch_i.release() );
+					mesh.add_channel( ch_i.release() );
 				}
 				else if ( command == "numweights" )
@@ -235,7 +236,8 @@
 			}
 
-			prepare_mesh( nodes, weight_info.size(), mesh, weights.data(), weight_info.data() );
-
-			m_meshes[ num_meshes ] = mesh;
+			data_channel_set* mdata = mesh.release();
+			prepare_mesh( nodes, weight_info.size(), mdata, weights.data(), weight_info.data() );
+
+			m_meshes[ num_meshes ] = mdata;
 			num_meshes++;
 		} // mesh
@@ -258,5 +260,5 @@
 				nodes[i].data      = new key_data;
 				data_channel_creator< md5_key_t > fc( num_frames );
-				nodes[i].data->add_channel( fc.release() );
+				nodes[i].data->add_key_channel( fc.release() );
 				next_line( sstream ); 
 			}
@@ -335,5 +337,5 @@
 }
 
-bool md5_loader::prepare_mesh( mesh_node_data* nodes, uint32 vtx_count, mesh_data* mdata, md5_weight* weights, md5_weight_info* weight_info )
+bool md5_loader::prepare_mesh( mesh_node_data* nodes, uint32 vtx_count, data_channel_set* mdata, md5_weight* weights, md5_weight_info* weight_info )
 {
 	assert( m_type == MESH );
@@ -400,9 +402,9 @@
 	}
 
-	const uint32*    idata = reinterpret_cast< uint32* >( const_cast< uint8* >( mdata->get_index_channel()->raw_data() ) );
+	const uint32*    idata = reinterpret_cast< uint32* >( const_cast< uint8* >( mdata->get_channel( slot::INDEX )->raw_data() ) );
 	const md5_vtx_t* tdata = mdata->get_channel_data<md5_vtx_t>();
 
 	// Prepare normals
-	uint32 tri_count = mdata->get_count() / 3;
+	uint32 tri_count = mdata->get_channel_size( slot::INDEX ) / 3;
 	for ( unsigned int i = 0; i < tri_count; ++i )
 	{
@@ -503,7 +505,7 @@
 }
 
-mesh_data* nv::md5_loader::release_mesh_data( size_t index )
-{
-	mesh_data* result = m_meshes[ index ];
+data_channel_set* nv::md5_loader::release_mesh_data( size_t index )
+{
+	data_channel_set* result = m_meshes[ index ];
 	m_meshes[ index ] = nullptr;
 	return result;
@@ -520,8 +522,8 @@
 {
 	uint32 size = m_meshes.size();
-	mesh_data* meshes = new mesh_data[ size ];
+	data_channel_set* meshes = data_channel_set_creator::create_array( size, 4 );
 	for ( uint32 i = 0; i < size; ++i )
 	{
-		m_meshes[i]->move_to( meshes[i] );
+		data_channel_set_creator( m_meshes[i] ).move_to( meshes[i] );
 		delete m_meshes[i];
 		m_meshes[i] = nullptr;
Index: trunk/src/formats/nmd_loader.cc
===================================================================
--- trunk/src/formats/nmd_loader.cc	(revision 415)
+++ trunk/src/formats/nmd_loader.cc	(revision 416)
@@ -8,4 +8,5 @@
 #include "nv/io/std_stream.hh"
 #include "nv/stl/string.hh"
+#include "nv/interface/data_channel_access.hh"
 
 using namespace nv;
@@ -34,5 +35,5 @@
 bool nv::nmd_loader::load_mesh( stream& source, const nmd_element_header& e )
 {
-	mesh_data* mesh = new mesh_data();
+	data_channel_set_creator mesh;
 	for ( uint32 s = 0; s < e.children; ++s )
 	{
@@ -45,15 +46,15 @@
 		raw_data_channel_creator channel_creator( stream_header.format, stream_header.count );
 		source.read( channel_creator.raw_data(), channel_creator.element_size(), channel_creator.size() );
-		mesh->add_channel( channel_creator.release() );
+		mesh.add_channel( channel_creator.release() );
 	}
 	m_mesh_names.push_back( e.name );
-	m_meshes.push_back( mesh );
-	return true;
-}
-
-mesh_data* nv::nmd_loader::release_mesh_data( size_t index )
-{
-	mesh_data* result = m_meshes[ index ];
-	if ( m_strings ) result->set_name( m_strings->get( m_mesh_names[ index ] ) );
+	m_meshes.push_back( mesh.release() );
+	return true;
+}
+
+data_channel_set* nv::nmd_loader::release_mesh_data( size_t index )
+{
+	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;
@@ -63,8 +64,8 @@
 {
 	uint32 size = m_meshes.size();
-	mesh_data* meshes = new mesh_data[ size ];
+	data_channel_set* meshes = data_channel_set_creator::create_array( size, 0 );
 	for ( uint32 i = 0; i < size; ++i )
 	{
-		m_meshes[i]->move_to( meshes[i] );
+		data_channel_set_creator( m_meshes[i] ).move_to( meshes[i] );
 		delete m_meshes[i];
 	}
@@ -130,5 +131,5 @@
 				raw_data_channel_creator channel_creator( cheader.format, cheader.count );
 				source.read( channel_creator.raw_data(), channel_creator.element_size(), channel_creator.size() );
-				kdata->add_channel( channel_creator.release() );
+				kdata->add_key_channel( channel_creator.release() );
 			}
 		}
@@ -160,10 +161,8 @@
 // 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 )
-{
-	array_view< raw_data_channel* > data  = mesh->get_raw_channels();
-
+static void nmd_dump_mesh( const data_channel_set* mesh, stream& stream_out )
+{
 	uint32 size = sizeof( nmd_element_header );
-	for ( auto chan : data )
+	for ( auto chan : *mesh )
 	{
 		size += sizeof( nmd_element_header ) + sizeof( nmd_stream_header );
@@ -174,9 +173,9 @@
 	eheader.type     = nmd_type::MESH;
 	eheader.name     = 0;
-	eheader.children = static_cast< uint16 >( data.size() );
+	eheader.children = static_cast< uint16 >( mesh->size() );
 	eheader.size     = size;
 	stream_out.write( &eheader, sizeof( eheader ), 1 );
 
-	for ( auto chan : data )
+	for ( auto chan : *mesh )
 	{
 		nmd_element_header cheader;
@@ -203,5 +202,5 @@
 		total += sizeof( nmd_element_header ) + sizeof( nmd_node_header );
 		if ( node->data )
-			for ( uint32 c = 0; c < node->data->get_channel_count(); ++c )
+			for ( uint32 c = 0; c < node->data->size(); ++c )
 			{
 				total += sizeof( nmd_element_header ) + sizeof( nmd_stream_header );
@@ -227,5 +226,5 @@
 		const mesh_node_data* node = nodes->get_node(i);
 		uint32 chan_size  = 0;
-		uint32 chan_count = ( node->data ? node->data->get_channel_count() : 0 );
+		uint32 chan_count = ( node->data ? node->data->size() : 0 );
 		for ( uint32 c = 0; c < chan_count; ++c )
 		{
@@ -280,5 +279,5 @@
 	for ( uint32 i = 0; i < model->get_count(); ++i )
 	{
-		const mesh_data* mesh = model->get_mesh(i);
+		const data_channel_set* mesh = model->get_mesh(i);
 		nmd_dump_mesh( mesh, stream_out );
 	}
Index: trunk/src/formats/obj_loader.cc
===================================================================
--- trunk/src/formats/obj_loader.cc	(revision 415)
+++ trunk/src/formats/obj_loader.cc	(revision 416)
@@ -7,4 +7,6 @@
 #include "nv/formats/obj_loader.hh"
 #include "nv/io/std_stream.hh"
+#include "nv/interface/data_channel_access.hh"
+
 #include <sstream>
 
@@ -330,7 +332,7 @@
 		}
 
-		mesh_data* mesh = new mesh_data(reader->name);
-		mesh->add_channel( channel.release() );
-		m_meshes.push_back( mesh );
+		data_channel_set_creator result;// ( reader->name );
+		result.add_channel( channel.release() );
+		m_meshes.push_back( result.release() );
 
 		reader->reset();
@@ -341,7 +343,7 @@
 }
 
-mesh_data* nv::obj_loader::release_mesh_data( size_t index )
-{
-	mesh_data* result = m_meshes[ index ];
+data_channel_set* nv::obj_loader::release_mesh_data( size_t index )
+{
+	data_channel_set* result = m_meshes[ index ];
 	m_meshes[ index ] = nullptr;
 	return result;
@@ -356,8 +358,8 @@
 {
 	uint32 size = m_meshes.size();
-	mesh_data* meshes = new mesh_data[ size ];
+	data_channel_set* meshes = data_channel_set_creator::create_array( size, 1 );
 	for ( uint32 i = 0; i < size; ++i )
 	{
-		m_meshes[i]->move_to( meshes[i] );
+		data_channel_set_creator( m_meshes[i] ).move_to( meshes[i] );
 		delete m_meshes[i];
 	}
Index: trunk/src/gfx/keyframed_mesh.cc
===================================================================
--- trunk/src/gfx/keyframed_mesh.cc	(revision 415)
+++ trunk/src/gfx/keyframed_mesh.cc	(revision 416)
@@ -23,5 +23,5 @@
 	, m_active( false )
 {
-	m_index_count  = m_mesh_data->get_index_channel()->size();
+	m_index_count  = m_mesh_data->get_channel( slot::INDEX )->size();
 	m_vertex_count = m_mesh_data->get_channel<vertex_t>()->size();
 	m_vchannel     = m_mesh_data->get_channel<vertex_pnt>();
@@ -190,8 +190,7 @@
 	m_context->add_vertex_buffers( m_va, vb, m_mesh_data->get_channel<vertex_t>() );
 
-	const raw_data_channel* index_channel = m_mesh_data->get_index_channel();
+	const raw_data_channel* index_channel = m_mesh_data->get_channel( slot::INDEX );
 	buffer  ib = m_context->get_device()->create_buffer( INDEX_BUFFER, STATIC_DRAW, index_channel->raw_size(), index_channel->raw_data() );
-
-	m_context->set_index_buffer( m_va, ib, m_mesh_data->get_index_channel()->descriptor()[0].etype, true );
+	m_context->set_index_buffer( m_va, ib, index_channel->descriptor()[0].etype, true );
 
 	m_data = new uint8[ m_vertex_count * m_vsize ];
Index: trunk/src/gfx/mesh_creator.cc
===================================================================
--- trunk/src/gfx/mesh_creator.cc	(revision 415)
+++ trunk/src/gfx/mesh_creator.cc	(revision 416)
@@ -6,4 +6,6 @@
 
 #include "nv/gfx/mesh_creator.hh"
+
+#include "nv/interface/data_channel_access.hh"
 
 struct nv_key_transform { nv::transform tform; };
@@ -22,5 +24,5 @@
 		size_t pcount    = ( pkeys ? pkeys->get_channel(0)->size() : 0 );
 		max_frames = nv::max<uint32>( count, max_frames );
-		if ( pkeys && pkeys->get_channel_count() > 0 && keys && keys->get_channel_count() > 0 )
+		if ( pkeys && pkeys->size() > 0 && keys && keys->size() > 0 )
 		{
 			data_channel_creator< nv_key_transform > channel_creator( const_cast< raw_data_channel* >( keys->get_channel( 0 ) ) );
@@ -54,7 +56,7 @@
 	{
 		key_data* old_keys = m_data->m_nodes[i].data;
-		if ( old_keys && old_keys->get_channel_count() > 0 )
-		{
-			size_t chan_count = old_keys->get_channel_count();
+		if ( old_keys && old_keys->size() > 0 )
+		{
+			size_t chan_count = old_keys->size();
 			if ( chan_count == 1 
 				&& old_keys->get_channel(0)->descriptor().size() == 1
@@ -85,5 +87,5 @@
 
 			delete old_keys;
-			new_keys->add_channel( kt_channel.release() );
+			new_keys->add_key_channel( kt_channel.release() );
 			m_data->m_nodes[i].data = new_keys;
 		}
@@ -104,5 +106,5 @@
 		{
 			key_data* kdata  = node.data;
-			for ( size_t c = 0; c < kdata->get_channel_count(); ++c )
+			for ( size_t c = 0; c < kdata->size(); ++c )
 			{
 				raw_data_channel_creator channel( const_cast< raw_data_channel* >( kdata->get_channel( c ) ) );
@@ -123,7 +125,7 @@
 	mat3 normal_transform  = r33;
 
-	for ( uint32 c = 0; c < m_data->get_channel_count(); ++c )
-	{
-		raw_data_channel_creator channel( m_data->m_channels[ c ] );
+	for ( uint32 c = 0; c < m_data->size(); ++c )
+	{
+		raw_data_channel_creator channel( m_data, c );
 		const data_descriptor&  desc    = channel.descriptor();
 		uint8* raw_data = channel.raw_data();
@@ -173,5 +175,5 @@
 	size_t n_offset = 0;
 	if ( ch_n == -1 ) return;
-	raw_data_channel_creator channel( m_data->m_channels[ unsigned( ch_n ) ] );
+	raw_data_channel_creator channel( m_data, unsigned( ch_n ) );
 	for ( const auto& cslot : channel.descriptor() )
 		if ( cslot.vslot == slot::NORMAL )
@@ -201,5 +203,5 @@
 	const raw_data_channel* i_channel = nullptr;
 
-	for ( uint32 c = 0; c < m_data->get_channel_count(); ++c )
+	for ( uint32 c = 0; c < m_data->size(); ++c )
 	{
 		const raw_data_channel* channel = m_data->get_channel(c);
@@ -219,5 +221,5 @@
 				{
 					n_offset  = int( cslot.offset );
-					n_channel = m_data->m_channels[ c ];
+					n_channel = data_channel_set_creator( m_data )[ c ];
 					n_channel_index = c;
 				}
@@ -331,9 +333,9 @@
 	delete tangents2;
 
-	m_data->m_channels[ n_channel_index ] = merge_channels( n_channel, g_channel.channel() );
+	( data_channel_set_creator( m_data ))[ n_channel_index ] = merge_channels( n_channel, g_channel.channel() );
 	delete n_channel;
 }
 
-nv::raw_data_channel* nv::mesh_data_creator::merge_channels( raw_data_channel* a, raw_data_channel* b )
+nv::raw_data_channel* nv::mesh_data_creator::merge_channels( const raw_data_channel* a, const raw_data_channel* b )
 {
 	NV_ASSERT( a->size() == b->size(), "merge_channel - bad channels!" );
@@ -351,5 +353,5 @@
 }
 
-nv::raw_data_channel* nv::mesh_data_creator::append_channels( raw_data_channel* a, raw_data_channel* b, uint32 frame_count )
+nv::raw_data_channel* nv::mesh_data_creator::append_channels( const raw_data_channel* a, const raw_data_channel* b, uint32 frame_count )
 {
 	if ( a->descriptor() != b->descriptor() ) return nullptr;
@@ -389,6 +391,6 @@
 bool nv::mesh_data_creator::is_same_format( mesh_data* other )
 {
-	if ( m_data->get_channel_count() != other->get_channel_count() ) return false;
-	for ( uint32 c = 0; c < m_data->get_channel_count(); ++c )
+	if ( m_data->size() != other->size() ) return false;
+	for ( uint32 c = 0; c < m_data->size(); ++c )
 	{
 		if ( m_data->get_channel(c)->descriptor() != other->get_channel(c)->descriptor() )
@@ -406,18 +408,20 @@
 	int och_ti = other->get_channel_index( slot::TEXCOORD );
 	if ( ch_pi == -1 || ch_ti == -1 ) return;
-	size_t size   = m_data->m_channels[ unsigned(ch_ti) ]->size();
-	size_t osize  =  other->m_channels[ unsigned(och_ti) ]->size();
-	size_t count  = m_data->m_channels[ unsigned(ch_pi) ]->size();
-	size_t ocount =  other->m_channels[ unsigned(och_pi) ]->size();
+	size_t size   = m_data->get_channel_size( unsigned(ch_ti) );
+	size_t osize  =  other->get_channel_size( unsigned(och_ti) );
+	size_t count  = m_data->get_channel_size( unsigned(ch_pi) );
+	size_t ocount =  other->get_channel_size( unsigned(och_pi) );
 	if ( count % size != 0 || ocount % osize != 0 ) return;
 	if ( count / size != ocount / osize ) return;
 	
-	for ( uint32 c = 0; c < m_data->get_channel_count(); ++c )
-	{
-		raw_data_channel* old = m_data->m_channels[c];
+	data_channel_set_creator data( m_data );
+
+	for ( uint32 c = 0; c < m_data->size(); ++c )
+	{
+		const raw_data_channel* old = m_data->get_channel( c );
 		bool old_is_index = old->size() > 0 && old->descriptor()[0].vslot == slot::INDEX;
 		size_t frame_count = ( old_is_index ? 1 : old->size() / size );
-		m_data->m_channels[c] = append_channels( old, other->m_channels[c], frame_count );
-		NV_ASSERT( m_data->m_channels[c], "Merge problem!" );
+		data[c] = append_channels( old, other->get_channel(c), frame_count );
+		NV_ASSERT( data[c], "Merge problem!" );
 		if ( old_is_index )
 		{
@@ -427,5 +431,5 @@
 				{
 					NV_ASSERT( size + osize < uint16(-1), "Index out of range!" );
-					raw_data_channel_creator ic( m_data->m_channels[c] );
+					raw_data_channel_creator ic( data[c] );
 					uint16* indexes = reinterpret_cast<uint16*>( ic.raw_data() );
 					for ( uint16 i = uint16( old->size() ); i < ic.size(); ++i )
@@ -436,5 +440,5 @@
 			case UINT   : 
 				{
-					raw_data_channel_creator ic( m_data->m_channels[c] );
+					raw_data_channel_creator ic( data[c] );
 					uint32* indexes = reinterpret_cast<uint32*>( ic.raw_data() );
 					for ( uint32 i = old->size(); i < ic.size(); ++i )
@@ -444,7 +448,16 @@
 			default : NV_ASSERT( false, "Unsupported index type!" ); break;
 			}
-			m_data->m_index_channel = m_data->m_channels[c];
 		}
 		delete old;
 	}
 }
+
+void nv::mesh_creator::delete_mesh( uint32 index )
+{
+	if ( index < m_pack->get_count() )
+	{
+		data_channel_set_creator( &m_pack->m_meshes[index] ).destroy();
+		data_channel_set_creator( &m_pack->m_meshes[m_pack->m_count - 1] ).move_to( m_pack->m_meshes[index] );
+		m_pack->m_count--;
+	}
+}
Index: trunk/src/gfx/skeletal_mesh.cc
===================================================================
--- trunk/src/gfx/skeletal_mesh.cc	(revision 415)
+++ trunk/src/gfx/skeletal_mesh.cc	(revision 416)
@@ -27,11 +27,11 @@
 
 	m_vtx_data  = a_mesh_data->get_channel_data<md5_vtx_pntiw>();
-	m_indices   = a_mesh_data->get_count();
+	m_indices   = a_mesh_data->get_channel_size( slot::INDEX );
 	m_va        = a_context->create_vertex_array();
 
-	array_view< raw_data_channel* > channels = a_mesh_data->get_raw_channels();
-	for ( uint32 ch = 0; ch < channels.size(); ++ch )
-	{
-		const raw_data_channel* channel = channels[ch];
+	//array_view< raw_data_channel* > channels = a_mesh_data->get_raw_channels();
+	for ( auto channel : *a_mesh_data )
+	{
+		//const raw_data_channel* channel = channels[ch];
 		if ( channel->size() > 0 && channel != pntiw_chan )
 		{
@@ -218,5 +218,5 @@
 {
 	m_va          = a_context->create_vertex_array( a_mesh, nv::STATIC_DRAW );
-	m_index_count = a_mesh->get_count();
+	m_index_count = a_mesh->get_channel_size( slot::INDEX );
 	if ( m_bone_data )
 	{
