Index: trunk/src/formats/assimp_loader.cc
===================================================================
--- trunk/src/formats/assimp_loader.cc	(revision 416)
+++ trunk/src/formats/assimp_loader.cc	(revision 417)
@@ -124,6 +124,8 @@
 	else
 		desc.initialize< assimp_plain_vtx >();
-	raw_data_channel_creator channel( desc, mesh->mNumVertices );
-	uint8* cdata = channel.raw_data();
+	data_channel_set_creator maccess( data );
+	maccess.set_name( mesh->mName.data );
+	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() );
 
 	if ( mesh->mTangents && mesh->mBitangents )
@@ -171,6 +173,4 @@
 	}
 
-	data_channel_creator< index_u16 > ichannel( mesh->mNumFaces * 3 );
-	uint16* indices = reinterpret_cast<uint16*>( ichannel.raw_data() );
 	for (unsigned int i=0; i<mesh->mNumFaces; i++)
 	{
@@ -182,8 +182,4 @@
 	}
 
-	data_channel_set_creator maccess( data );
-	maccess.set_name( mesh->mName.data );
-	maccess.add_channel( channel.release() );
-	maccess.add_channel( ichannel.release() );
 }
 
@@ -321,5 +317,5 @@
 			if ( m > 0 && bones.size() > 0 )
 			{
-				data_channel_creator< assimp_skinned_vtx > channel( const_cast< raw_data_channel* >( meshes[m].get_channel(0) ) );
+				data_channel_access< assimp_skinned_vtx > channel( const_cast< raw_data_channel* >( meshes[m].get_channel(0) ) );
 				for ( unsigned v = 0; v < channel.size(); ++v )
 				{
@@ -422,12 +418,10 @@
 	}
 
-	data->data = new key_data;
-	data_channel_creator< assimp_key_p > pchannel_creator( node->mNumPositionKeys );
-	data_channel_creator< assimp_key_r > rchannel_creator( node->mNumRotationKeys );
-//	data_channel_creator< assimp_key_s > schannel_creator( node->mNumScalingKeys );
-
-	assimp_key_p* pchannel = pchannel_creator.data();
-	assimp_key_r* rchannel = rchannel_creator.data();
-	//assimp_key_s* schannel = ((assimp_key_s*)(raw_schannel->data));
+	data->data = key_channel_set_creator::create( 2 );
+	key_channel_set_creator key_set( data->data );
+
+	assimp_key_p* pchannel = key_set.add_channel< assimp_key_p >( node->mNumPositionKeys ).data();
+	assimp_key_r* rchannel = key_set.add_channel< assimp_key_r >( node->mNumRotationKeys ).data();
+//	assimp_key_s* schannel = key_set.add_channel< assimp_key_s >( node->mNumScalingKeys ).data();
 
 	for ( unsigned np = 0; np < node->mNumPositionKeys; ++np )
@@ -460,7 +454,5 @@
 // 		}
 // 	}
-	data->data->add_key_channel( pchannel_creator.release() );
-	data->data->add_key_channel( rchannel_creator.release() );
-//	data->data->add_key_channel( schannel_creator.release() );
+
 }
 
Index: trunk/src/formats/md2_loader.cc
===================================================================
--- trunk/src/formats/md2_loader.cc	(revision 416)
+++ trunk/src/formats/md2_loader.cc	(revision 417)
@@ -326,6 +326,8 @@
 	size_t frame_count   = ( frame == -1 ? num_frames : 1 );
 
-	data_channel_creator< vtx_md2_pn > mc_pn( num_verts * frame_count );
-	vtx_md2_pn* vtx_pn = mc_pn.data();
+	data_channel_set_creator maccess( data );
+	vtx_md2_pn* vtx_pn = maccess.add_channel< vtx_md2_pn >( num_verts * frame_count ).data();
+	vtx_md2_t* vtx_t   = maccess.add_channel< vtx_md2_t >( num_verts ).data();
+	uint16* icp        = &maccess.add_channel< index_u16 >( m_new_indexes.size() ).data()->index;
 
 	uint32 index = 0;
@@ -349,7 +351,4 @@
 	}
 
-	data_channel_creator< vtx_md2_t > mc_t( num_verts );
-	vtx_md2_t* vtx_t = mc_t.data();
-
 	vec2 scale( 1.0f / static_cast<float>( md2->header.skinwidth ), 1.0f / static_cast<float>( md2->header.skinheight ) );
 	for (size_t i = 0; i < num_verts; ++i )
@@ -359,16 +358,9 @@
 	}
 
-	data_channel_creator< index_u16 > ic( m_new_indexes.size() );
 	if ( m_new_indexes.size() > 0 )
 	{
-		uint16* icp = reinterpret_cast< uint16* >( ic.raw_data() );
 		raw_copy_n( m_new_indexes.data(), m_new_indexes.size(), icp );
 	}
 
-	data_channel_set_creator maccess( data );
-
-	maccess.add_channel( mc_pn.release() );
-	maccess.add_channel( mc_t.release() );
-	maccess.add_channel( ic.release() );
 }
 
Index: trunk/src/formats/md3_loader.cc
===================================================================
--- trunk/src/formats/md3_loader.cc	(revision 416)
+++ trunk/src/formats/md3_loader.cc	(revision 417)
@@ -287,8 +287,8 @@
 }
 
-nv::raw_data_channel* nv::md3_loader::load_tags( const string_view& tag )
+void nv::md3_loader::load_tags( raw_data_channel* channel, const string_view& tag )
 {
 	md3_t* md3 = reinterpret_cast< md3_t* >( m_md3 );
-	data_channel_creator< md3_key > result( uint32( md3->header.num_frames ) );
+	data_channel_access< md3_key > access( channel );
 	// TODO: is this brain damaged in efficiency (loop nest order) or what?
 	for ( sint32 f = 0; f < md3->header.num_frames; ++f )
@@ -304,10 +304,9 @@
 				vec3 axisy  ( md3_vec3( rtag.axis[2] ) );
 				vec3 origin ( md3_vec3( rtag.origin )  );
-				result.data()[f].tform = transform( origin, quat( mat3( axisx, axisy, axisz ) ) );
+				access.data()[f].tform = transform( origin, quat( mat3( axisx, axisy, axisz ) ) );
 			}
 		}
 
 	}
-	return result.release();
 }
 
@@ -353,10 +352,10 @@
 		}
 
-	data_channel_creator< vtx_md3_pn > mc_pn( static_cast< uint32 >( num_verts * frame_count ) );
-	data_channel_creator< vtx_md3_t > mc_t( static_cast< uint32 >( num_verts ) );
-	data_channel_creator< index_u16 > ic( static_cast< uint32 >( index_count ) );
-	vtx_md3_pn* vtx_pn = mc_pn.data();
-	vtx_md3_t*  vtx_t = mc_t.data();
-	uint16*     icp    = &(ic.data()[0].index);
+	data_channel_set_creator maccess( data );
+	maccess.set_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();
+	vtx_md3_t*  vtx_t  = maccess.add_channel< vtx_md3_t >( static_cast< uint32 >( num_verts ) ).data();
+	uint16*     icp    = reinterpret_cast< uint16* >( maccess.add_channel< index_u16 >( static_cast< uint32 >( index_count ) ).data() );
 
 	uint32 index  = 0;
@@ -413,9 +412,4 @@
 	}
 
-	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() );
 }
 
@@ -435,8 +429,6 @@
 		nodes[i].parent_id = -1;
 		nodes[i].target_id = -1;
-		nodes[i].data      = new key_data;
-	
-		raw_data_channel* keys = load_tags( name );
-		nodes[i].data->add_key_channel( keys );
+		nodes[i].data      = key_channel_set_creator::create( 1 );
+		load_tags( key_channel_set_creator( nodes[i].data ).add_channel<md3_key>( uint32( md3->header.num_frames ) ).channel(), name );
 	}
 	return new mesh_nodes_data( "tags", node_count, nodes );
Index: trunk/src/formats/md5_loader.cc
===================================================================
--- trunk/src/formats/md5_loader.cc	(revision 416)
+++ trunk/src/formats/md5_loader.cc	(revision 417)
@@ -137,5 +137,6 @@
 		{
 			assert( m_type == MESH );
-			data_channel_set_creator mesh;
+			data_channel_set* mesh = data_channel_set_creator::create( 4 );
+			data_channel_set_creator maccess( mesh );
 
 			uint32 num_verts   = 0;
@@ -160,13 +161,7 @@
 					md5_vtx_t* tdata = nullptr;
 					{
-						data_channel_creator<md5_vtx_pnt>   ch_pnt( num_verts );
-						data_channel_creator<md5_vtx_t>     ch_t( num_verts );
-						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() );
-						// TODO: hack to prevent rendering
-						//ch_pntiw->m_count = 0;
-						mesh.add_channel( ch_pntiw.release() );
+						maccess.add_channel<md5_vtx_pnt>( num_verts );
+						tdata = maccess.add_channel<md5_vtx_t>( num_verts ).data();
+						maccess.add_channel<md5_vtx_pntiw>( num_verts );
 					}
 					weight_info.resize( num_verts );
@@ -191,6 +186,5 @@
 					sstream >> num_tris;
 
-					data_channel_creator< index_u32 > ch_i( num_tris * 3 );
-					uint32* vtx_i                = reinterpret_cast< uint32* >( ch_i.raw_data() );
+					uint32* vtx_i = reinterpret_cast< uint32* >( maccess.add_channel< index_u32 >( num_tris * 3 ).raw_data() );
 					uint32 idx = 0;
 
@@ -211,5 +205,4 @@
 					}              
 
-					mesh.add_channel( ch_i.release() );
 				}
 				else if ( command == "numweights" )
@@ -236,8 +229,7 @@
 			}
 
-			data_channel_set* mdata = mesh.release();
-			prepare_mesh( nodes, weight_info.size(), mdata, weights.data(), weight_info.data() );
-
-			m_meshes[ num_meshes ] = mdata;
+			prepare_mesh( nodes, weight_info.size(), mesh, weights.data(), weight_info.data() );
+
+			m_meshes[ num_meshes ] = mesh;
 			num_meshes++;
 		} // mesh
@@ -258,8 +250,7 @@
 				nodes[i].transform = mat4();
 				nodes[i].target_id = -1;
-				nodes[i].data      = new key_data;
-				data_channel_creator< md5_key_t > fc( num_frames );
-				nodes[i].data->add_key_channel( fc.release() );
-				next_line( sstream ); 
+				nodes[i].data = key_channel_set_creator::create( 1 );
+				key_channel_set_creator( nodes[i].data ).add_channel< md5_key_t >( num_frames );
+				next_line( sstream );
 			}
 			discard( sstream, "}" );
@@ -340,6 +331,6 @@
 {
 	assert( m_type == MESH );
-	data_channel_creator< md5_vtx_pnt >   pnt  ( const_cast< raw_data_channel* >( mdata->get_channel< md5_vtx_pnt >() ) );
-	data_channel_creator< md5_vtx_pntiw > pntiw( const_cast< raw_data_channel* >( mdata->get_channel< md5_vtx_pntiw >() ) );
+	data_channel_access< md5_vtx_pnt >   pnt  ( const_cast< raw_data_channel* >( mdata->get_channel< md5_vtx_pnt >() ) );
+	data_channel_access< md5_vtx_pntiw > pntiw( const_cast< raw_data_channel* >( mdata->get_channel< md5_vtx_pntiw >() ) );
 	md5_vtx_pntiw* vtx_data = pntiw.data();
 	md5_vtx_pnt* vtcs = pnt.data();
Index: trunk/src/formats/nmd_loader.cc
===================================================================
--- trunk/src/formats/nmd_loader.cc	(revision 416)
+++ trunk/src/formats/nmd_loader.cc	(revision 417)
@@ -35,5 +35,6 @@
 bool nv::nmd_loader::load_mesh( stream& source, const nmd_element_header& e )
 {
-	data_channel_set_creator mesh;
+	data_channel_set* mesh = data_channel_set_creator::create( e.children );
+	data_channel_set_creator mcreator( mesh );
 	for ( uint32 s = 0; s < e.children; ++s )
 	{
@@ -44,10 +45,9 @@
 		nmd_stream_header stream_header;
 		source.read( &stream_header, sizeof( stream_header ), 1 );
-		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() );
+		raw_data_channel_access channel( mcreator.add_channel( stream_header.format, stream_header.count ) );
+		source.read( channel.raw_data(), channel.element_size(), channel.size() );
 	}
 	m_mesh_names.push_back( e.name );
-	m_meshes.push_back( mesh.release() );
+	m_meshes.push_back( mesh );
 	return true;
 }
@@ -121,5 +121,6 @@
 		if ( ch_count > 0 )
 		{
-			key_data* kdata = new key_data;
+			key_channel_set* kdata = key_channel_set_creator::create( ch_count );
+			key_channel_set_creator kaccess( kdata );
 			m_node_array[i].data = kdata;
 			for ( uint32 c = 0; c < ch_count; ++c )
@@ -129,7 +130,6 @@
 				nv::nmd_stream_header cheader;
 				source.read( &cheader, sizeof( cheader ), 1 );
-				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_key_channel( channel_creator.release() );
+				raw_data_channel_access channel( kaccess.add_channel( cheader.format, cheader.count ) );
+				source.read( channel.raw_data(), channel.element_size(), channel.size() );
 			}
 		}
Index: trunk/src/formats/obj_loader.cc
===================================================================
--- trunk/src/formats/obj_loader.cc	(revision 416)
+++ trunk/src/formats/obj_loader.cc	(revision 417)
@@ -326,13 +326,14 @@
 		}
 	
-		raw_data_channel_creator channel( m_descriptor, reader->size * 3 );
+		data_channel_set* result = data_channel_set_creator::create( 1 );
+		data_channel_set_creator raccess( result );// ( reader->name );
+		uint8* rdata = raccess.add_channel( m_descriptor, reader->size * 3 ).raw_data();
+
 		if ( reader->raw_size() > 0 )
 		{
-			raw_copy_n( reader->raw_pointer(), reader->raw_size(), channel.raw_data() );
-		}
-
-		data_channel_set_creator result;// ( reader->name );
-		result.add_channel( channel.release() );
-		m_meshes.push_back( result.release() );
+			raw_copy_n( reader->raw_pointer(), reader->raw_size(), rdata );
+		}
+
+		m_meshes.push_back( result );
 
 		reader->reset();
