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];
 	}
