Index: trunk/src/formats/md5_loader.cc
===================================================================
--- trunk/src/formats/md5_loader.cc	(revision 236)
+++ trunk/src/formats/md5_loader.cc	(revision 239)
@@ -90,5 +90,6 @@
 		else if ( command == "mesh" )
 		{
-			md5_mesh* mesh = new md5_mesh;
+			md5_mesh_data* mesh = new md5_mesh_data();
+
 			int num_verts, num_tris, num_weights;
 
@@ -99,6 +100,6 @@
 				if ( command == "shader" )
 				{
-					sstream >> mesh->shader;
-					remove_quotes( mesh->shader );
+					sstream >> mesh->m_shader;
+					remove_quotes( mesh->m_shader );
 					// texturePath.replace_extension( ".tga" );
 					next_line( sstream );
@@ -107,24 +108,29 @@
 				{
 					sstream >> num_verts; 
+
+					{
+						mesh_raw_channel* ch_pnt = mesh_raw_channel::create<md5_vtx_pnt>( num_verts );
+						mesh_raw_channel* ch_t   = mesh_raw_channel::create<md5_vtx_t>( num_verts );
+						mesh->m_pntdata          = (md5_vtx_pnt*)ch_pnt->data;
+						mesh->m_tdata            = (md5_vtx_t*)ch_t->data;
+						mesh->add_channel( ch_pnt );
+						mesh->add_channel( ch_t );
+					}
+					mesh->m_vtx_data.resize( num_verts );
+
 					next_line( sstream );
 					std::string line;
 					for ( int i = 0; i < num_verts; ++i )
 					{
-						md5_vertex vert;
+						md5_vtx_data& vdata = mesh->m_vtx_data[i];
+						size_t weight_count;
+						size_t start_weight;
+						vec2 texcoord;
 
 						std::getline( sstream, line );
-						sscanf( line.c_str(), "%*s %*u ( %f %f ) %u %u", &(vert.texcoord.x), &(vert.texcoord.y), &(vert.start_weight), &(vert.weight_count) );
-
-// 						std::string ignore;
-// 						discard( sstream, "vert" );
-// 						sstream >> ignore;
-// 						discard( sstream, "(" );
-// 						sstream >> vert.texcoord.x >> vert.texcoord.y;
-// 						discard( sstream, ")" );
-// 						sstream >> vert.start_weight >> vert.weight_count;
-// 						next_line( sstream );
-
-						mesh->verts.push_back(vert);
-						mesh->texcoord_buffer.push_back( vert.texcoord );
+						sscanf( line.c_str(), "%*s %*u ( %f %f ) %u %u", &(texcoord.x), &(texcoord.y), &(start_weight), &(weight_count) );
+						vdata.start_weight = start_weight;
+						vdata.weight_count = weight_count;
+						mesh->m_tdata[i].texcoord = texcoord;
 					}  
 				}
@@ -132,22 +138,25 @@
 				{
 					sstream >> num_tris;
+
+					mesh_raw_index_channel* ch_i = mesh_raw_index_channel::create<uint32>( num_tris * 3 );
+					uint32* vtx_i                = (uint32*)ch_i->data;
+					mesh->m_idata                = vtx_i;
+					uint32 idx = 0;
+					mesh->set_index_channel( ch_i );
+
 					next_line( sstream );
 					std::string line;
 					for ( int i = 0; i < num_tris; ++i )
 					{
-						md5_triangle tri;
+						size_t ti0;
+						size_t ti1;
+						size_t ti2;
 
 						std::getline( sstream, line );
-						sscanf( line.c_str(), "%*s %*u %u %u %u )", &(tri.indices[0]), &(tri.indices[1]), &(tri.indices[2]));
-
-// 						std::string ignore;
-// 						discard( sstream, "tri" );
-// 						sstream >> ignore >> tri.indices[0] >> tri.indices[1] >> tri.indices[2];
-// 						next_line( sstream );
-
-						mesh->tris.push_back( tri );
-						mesh->index_buffer.push_back( (uint32)tri.indices[0] );
-						mesh->index_buffer.push_back( (uint32)tri.indices[1] );
-						mesh->index_buffer.push_back( (uint32)tri.indices[2] );
+						sscanf( line.c_str(), "%*s %*u %u %u %u )", &(ti0), &(ti1), &(ti2));
+
+						vtx_i[idx++] = (uint32)ti0;
+						vtx_i[idx++] = (uint32)ti1;
+						vtx_i[idx++] = (uint32)ti2;
 					}              
 				}
@@ -155,5 +164,5 @@
 				{
 					sstream >> num_weights;
-					mesh->weights.reserve( num_weights );
+					mesh->m_weights.reserve( num_weights );
 					next_line( sstream );
 					std::string line;
@@ -164,13 +173,5 @@
 						std::getline( sstream, line );
 						sscanf( line.c_str(), "%*s %*u %u %f ( %f %f %f )", &(weight.joint_id), &(weight.bias), &(weight.pos.x), &(weight.pos.y), &(weight.pos.z));
-
-//  						std::string ignore;
-//  						discard( sstream, "weight" );
-//  						sstream >> ignore >> weight.joint_id >> weight.bias;
-//  						discard( sstream, "(" );
-//  						sstream >> weight.pos.x >> weight.pos.y >> weight.pos.z;
-//  						discard( sstream, ")" );
-//  						next_line( sstream );
- 						mesh->weights.push_back(weight);
+ 						mesh->m_weights.push_back(weight);
 					}
 				}
@@ -184,5 +185,4 @@
 
 			prepare_mesh( mesh );
-			prepare_normals( mesh );
 
 			m_meshes.push_back(mesh);
@@ -196,44 +196,40 @@
 }
 
-bool md5_loader::prepare_mesh( md5_mesh* mesh )
-{
-	mesh->position_buffer.clear();
-	mesh->texcoord_buffer.clear();
-
-	for ( uint32 i = 0; i < mesh->verts.size(); ++i )
-	{
-		md5_vertex& vert = mesh->verts[i];
-
-		vert.position = glm::vec3(0);
-		vert.normal   = glm::vec3(0);
-		vert.tangent  = glm::vec3(0);
-
-		for ( size_t j = 0; j < vert.weight_count; ++j )
-		{
-			md5_weight& weight = mesh->weights[vert.start_weight + j];
+bool md5_loader::prepare_mesh( md5_mesh_data* mdata )
+{
+	uint32 vtx_count = mdata->m_vtx_data.size();
+	md5_vtx_pnt* vtcs = mdata->m_pntdata;
+
+	for ( uint32 i = 0; i < vtx_count; ++i )
+	{
+		md5_vtx_data& vdata = mdata->m_vtx_data[i];
+		md5_vtx_pnt& vtc = vtcs[i];
+
+		vtc.position = glm::vec3(0);
+		vtc.normal   = glm::vec3(0);
+		vtc.tangent  = glm::vec3(0);
+
+		for ( size_t j = 0; j < vdata.weight_count; ++j )
+		{
+			md5_weight& weight = mdata->m_weights[vdata.start_weight + j];
 			md5_joint&  joint  = m_joints[weight.joint_id];
 
 			glm::vec3 rot_pos = joint.orient * weight.pos;
 
-			vert.position += ( joint.pos + rot_pos ) * weight.bias;
-		}
-
-		mesh->position_buffer.push_back(vert.position);
-		mesh->texcoord_buffer.push_back(vert.texcoord);
-	}
-
-	return true;
-}
-
-bool md5_loader::prepare_normals( md5_mesh* mesh )
-{
-	mesh->normal_buffer.clear();
-
-	for ( unsigned int i = 0; i < mesh->tris.size(); ++i )
-	{
-		const md5_triangle& tri = mesh->tris[i];
-		glm::vec3 v1 = mesh->verts[ tri.indices[0] ].position;
-		glm::vec3 v2 = mesh->verts[ tri.indices[1] ].position;
-		glm::vec3 v3 = mesh->verts[ tri.indices[2] ].position;
+			vtc.position += ( joint.pos + rot_pos ) * weight.bias;
+		}
+	}
+
+	// Prepare normals
+	uint32 tri_count = mdata->get_count() / 3;
+	for ( unsigned int i = 0; i < tri_count; ++i )
+	{
+		uint32 ti0 = mdata->m_idata[ i * 3 ];
+		uint32 ti1 = mdata->m_idata[ i * 3 + 1 ];
+		uint32 ti2 = mdata->m_idata[ i * 3 + 2 ];
+ 
+		glm::vec3 v1 = vtcs[ ti0 ].position;
+		glm::vec3 v2 = vtcs[ ti1 ].position;
+		glm::vec3 v3 = vtcs[ ti2 ].position;
 		glm::vec3 xyz1 = v3 - v1;
 		glm::vec3 xyz2 = v2 - v1;
@@ -241,11 +237,11 @@
 		glm::vec3 normal = glm::cross( xyz1, xyz2 );
 
-		mesh->verts[ tri.indices[0] ].normal += normal;
-		mesh->verts[ tri.indices[1] ].normal += normal;
-		mesh->verts[ tri.indices[2] ].normal += normal;
-
-		const vec2& w1 = mesh->verts[ tri.indices[0] ].texcoord;
-		const vec2& w2 = mesh->verts[ tri.indices[1] ].texcoord;
-		const vec2& w3 = mesh->verts[ tri.indices[2] ].texcoord;
+		vtcs[ ti0 ].normal += normal;
+		vtcs[ ti1 ].normal += normal;
+		vtcs[ ti2 ].normal += normal;
+
+		const vec2& w1 = mdata->m_tdata[ ti0 ].texcoord;
+		const vec2& w2 = mdata->m_tdata[ ti1 ].texcoord;
+		const vec2& w3 = mdata->m_tdata[ ti2 ].texcoord;
 
 		vec2 st1 = w3 - w1;
@@ -256,28 +252,28 @@
 		vec3 tangent = (( xyz1 * st2.y ) - ( xyz2 * st1.y )) * coef;
 
-		mesh->verts[ tri.indices[0] ].tangent += tangent;
-		mesh->verts[ tri.indices[1] ].tangent += tangent;
-		mesh->verts[ tri.indices[2] ].tangent += tangent;
-	}
-
-	for ( size_t i = 0; i < mesh->verts.size(); ++i )
-	{
-		md5_vertex& vert = mesh->verts[i];
-
-		glm::vec3 normal  = glm::normalize( vert.normal );
-		glm::vec3 tangent = glm::normalize( vert.tangent );
-		mesh->normal_buffer.push_back( normal );
-		mesh->tangent_buffer.push_back( tangent );
-
-		vert.normal  = glm::vec3(0);
-		vert.tangent = glm::vec3(0);
-
-		for ( size_t j = 0; j < vert.weight_count; ++j )
-		{
-			const md5_weight& weight = mesh->weights[vert.start_weight + j];
-			const md5_joint&  joint  = m_joints[weight.joint_id];
-			vert.normal  += ( normal  * joint.orient ) * weight.bias;
-			vert.tangent += ( tangent * joint.orient ) * weight.bias;
-		}
+		vtcs[ ti0 ].tangent += tangent;
+		vtcs[ ti1 ].tangent += tangent;
+		vtcs[ ti2 ].tangent += tangent;
+	}
+
+	for ( size_t i = 0; i < vtx_count; ++i )
+	{
+		md5_vtx_data& vdata = mdata->m_vtx_data[i];
+
+		glm::vec3 normal  = glm::normalize( vtcs[i].normal );
+		glm::vec3 tangent = glm::normalize( vtcs[i].tangent );
+		vtcs[i].normal   = normal;
+		vtcs[i].tangent  = tangent;
+
+ 		vdata.normal  = glm::vec3(0);
+ 		vdata.tangent = glm::vec3(0);
+ 
+ 		for ( size_t j = 0; j < vdata.weight_count; ++j )
+ 		{
+ 			const md5_weight& weight = mdata->m_weights[vdata.start_weight + j];
+ 			const md5_joint&  joint  = m_joints[weight.joint_id];
+ 			vdata.normal  += ( normal  * joint.orient ) * weight.bias;
+ 			vdata.tangent += ( tangent * joint.orient ) * weight.bias;
+ 		}
 	}
 
@@ -285,36 +281,4 @@
 }
 
-mesh_data_old* nv::md5_loader::release_submesh_data( uint32 mesh_id )
-{
-	mesh_data_creator m;
-	m.get_positions().assign( m_meshes[mesh_id]->position_buffer.begin(), m_meshes[mesh_id]->position_buffer.begin() );
-	m.get_normals()  .assign( m_meshes[mesh_id]->normal_buffer.begin(),   m_meshes[mesh_id]->normal_buffer.begin() );
-	m.get_tangents() .assign( m_meshes[mesh_id]->tangent_buffer.begin(),  m_meshes[mesh_id]->tangent_buffer.begin() );
-	m.get_texcoords().assign( m_meshes[mesh_id]->texcoord_buffer.begin(), m_meshes[mesh_id]->texcoord_buffer.begin() );
-	m.get_indices()  .assign( m_meshes[mesh_id]->index_buffer.begin(),    m_meshes[mesh_id]->index_buffer.begin() );
-
-	return m.release();
-}
-
-/*
-mesh* md5_loader::release_mesh()
-{
-	mesh* m = new mesh();
-	auto position = m->add_attribute< vec3 >( "nv_position" );
-	auto normal   = m->add_attribute< vec3 >( "nv_normal" );
-	auto texcoord = m->add_attribute< vec2 >( "nv_texcoord" );
-	auto tangent  = m->add_attribute< vec3 >( "nv_tangent" );
-	auto indices  = m->add_indices< uint32 >();
-
-	position->get().assign( m_meshes[0].position_buffer.begin(), m_meshes[0].position_buffer.end() );
-	normal  ->get().assign( m_meshes[0].normal_buffer.begin(),   m_meshes[0].normal_buffer.end() );
-	texcoord->get().assign( m_meshes[0].texcoord_buffer.begin(), m_meshes[0].texcoord_buffer.end() );
-	tangent ->get().assign( m_meshes[0].tangent_buffer.begin(),  m_meshes[0].tangent_buffer.end() );
-	indices ->get().assign( m_meshes[0].index_buffer.begin(),    m_meshes[0].index_buffer.end() );
-
-	m_size = m_meshes[0].index_buffer.size();
-	return m;
-}
-*/
 
 md5_animation::md5_animation()
@@ -570,44 +534,40 @@
 }
 
-bool md5_loader::prepare_animated_mesh( md5_mesh* mesh, const md5_animation::md5_frame_skeleton& skel )
-{
-	for ( unsigned int i = 0; i < mesh->verts.size(); ++i )
-	{
-		const md5_vertex& vert = mesh->verts[i];
-		glm::vec3& pos     = mesh->position_buffer[i];
-		glm::vec3& normal  = mesh->normal_buffer[i];
-		glm::vec3& tangent = mesh->tangent_buffer[i];
-
-		pos     = glm::vec3(0);
-		normal  = glm::vec3(0);
-		tangent = glm::vec3(0);
+mesh_data* nv::md5_loader::release_mesh_data( uint32 mesh )
+{
+	mesh_data* result = m_meshes[ mesh ];
+	m_meshes[ mesh ] = nullptr;
+	return result;
+}
+
+void nv::md5_mesh_data::apply( const md5_animation& animation )
+{
+	const md5_animation::md5_frame_skeleton& skeleton = animation.get_skeleton();
+
+	for ( unsigned int i = 0; i < m_vtx_data.size(); ++i )
+	{
+		const md5_vtx_data& vert = m_vtx_data[i];
+		md5_vtx_pnt& result = m_pntdata[i];
+
+		result.position = glm::vec3(0);
+		result.normal   = glm::vec3(0);
+		result.tangent  = glm::vec3(0);
 
 		for ( size_t j = 0; j < vert.weight_count; ++j )
 		{
-			const md5_weight& weight = mesh->weights[vert.start_weight + j];
-			const md5_animation::md5_skeleton_joint& joint = skel.joints[weight.joint_id];
+			const md5_weight& weight = m_weights[vert.start_weight + j];
+			const md5_animation::md5_skeleton_joint& joint = skeleton.joints[weight.joint_id];
 
 			glm::vec3 rot_pos = joint.orient * weight.pos;
-			pos += ( joint.pos + rot_pos ) * weight.bias;
-
-			normal  += ( joint.orient * vert.normal  ) * weight.bias;
-			tangent += ( joint.orient * vert.tangent ) * weight.bias;
-		}
-	}
-	return true;
-}
-
-void md5_loader::apply( const md5_animation& animation )
-{
-	const md5_animation::md5_frame_skeleton& skeleton = animation.get_skeleton();
-
-	for ( unsigned int i = 0; i < m_meshes.size(); ++i )
-	{
-		prepare_animated_mesh( m_meshes[i], skeleton );
-	}
-}
-
-size_t nv::md5_loader::get_size()
-{
-	return m_size;
-}
+			result.position += ( joint.pos + rot_pos ) * weight.bias;
+
+			result.normal  += ( joint.orient * vert.normal  ) * weight.bias;
+			result.tangent += ( joint.orient * vert.tangent ) * weight.bias;
+		}
+	}
+}
+
+nv::md5_loader::~md5_loader()
+{
+	for ( auto m : m_meshes ) { if (m) delete m; }
+}
