Index: trunk/src/formats/md3_loader.cc
===================================================================
--- trunk/src/formats/md3_loader.cc	(revision 302)
+++ trunk/src/formats/md3_loader.cc	(revision 304)
@@ -233,6 +233,6 @@
 static bool s_normal_ready = false;
 
-md3_loader::md3_loader()
-	: m_md3( nullptr )
+md3_loader::md3_loader( bool merge_all )
+	: m_md3( nullptr ), m_merge_all( merge_all )
 {
 	if ( !s_normal_ready )
@@ -319,28 +319,77 @@
 };
 
-mesh_data* nv::md3_loader::release_mesh_data( size_t )
+mesh_data* nv::md3_loader::release_mesh_data( size_t index )
 {
 	mesh_data* data = new mesh_data;
-	release_mesh_frame( data, -1 );
+	release_mesh_frame( data, -1, index );
 	return data;
 }
 
-void nv::md3_loader::release_mesh_frame( mesh_data* data, sint32 frame )
+void nv::md3_loader::release_mesh_frame( mesh_data* data, sint32 frame, sint32 surface )
 {
 	md3_t* md3 = (md3_t*)m_md3;
-	sint32 num_surfaces = md3->header.num_surfaces;
-	sint32 num_verts    = md3->vertices_per_frame;
+	sint32 num_surfaces  = md3->header.num_surfaces;
+	sint32 num_verts     = 0;
 	sint32 current_frame = ( frame == -1 ? 0 : frame );
 	sint32 frame_count   = ( frame == -1 ? md3->header.num_frames : 1 );
+	sint32 current_surf  = ( surface == -1 ? 0 : surface );
+	sint32 surf_count    = ( surface == -1 ? md3->header.num_surfaces : 1 );
+	sint32 index_count   = 0;
+
+	if ( surface >= 0 )
+	{
+		index_count = md3->surfaces[surface].header.num_triangles * 3;
+		num_verts   = md3->surfaces[surface].header.num_verts;
+	}
+	else
+		for ( sint32 i = 0; i < num_surfaces; ++i )
+		{
+			index_count += md3->surfaces[i].header.num_triangles * 3;
+			num_verts   += md3->surfaces[i].header.num_verts;
+		}
 
 	mesh_raw_channel* mc_pn = mesh_raw_channel::create< vtx_md3_pn >( num_verts * frame_count );
+	mesh_raw_channel* mc_t  = mesh_raw_channel::create< vtx_md3_t >( num_verts );
+	mesh_raw_channel* ic = mesh_raw_channel::create_index< uint16 >( index_count );
 	vtx_md3_pn* vtx_pn = (vtx_md3_pn*)mc_pn->data;
-
-	uint32 index = 0;
+	vtx_md3_t*  vtx_t  = (vtx_md3_t*) mc_t->data;
+	uint16*     icp    = (uint16*)ic->data;
+
+	uint32 index  = 0;
+	uint32 iindex = 0;
+	sint32 index_base = 0;
+
+	while ( surf_count > 0 )
+	{
+		const md3_surface_t& surface = md3->surfaces[ current_surf ];
+		const uint32         vcount  = static_cast< uint32 >( surface.header.num_verts );
+		const uint32         tcount  = static_cast< uint32 >( surface.header.num_triangles );
+
+		for (uint32 j = 0; j < vcount; ++j )
+		{
+			vtx_t[index++].texcoord = md3_texcoord( surface.st[j] );
+		}
+
+		for (size_t j = 0; j < tcount; ++j )
+		{
+			const md3_triangle_t& t = surface.triangles[j];
+			icp[iindex++] = static_cast< uint16 >( index_base + t.indexes[0] );
+			icp[iindex++] = static_cast< uint16 >( index_base + t.indexes[1] );
+			icp[iindex++] = static_cast< uint16 >( index_base + t.indexes[2] );
+		}
+		index_base += surface.header.num_verts;
+		++current_surf;
+		--surf_count;
+	}
+
+	index = 0;
 	while ( frame_count > 0 )
 	{
-		for ( sint32 i = 0; i < num_surfaces; ++i )
-		{
-			md3_surface_t& surface = md3->surfaces[i];
+		current_surf  = ( surface == -1 ? 0 : surface );
+		surf_count    = ( surface == -1 ? md3->header.num_surfaces : 1 );
+
+		while ( surf_count > 0 )
+		{
+			md3_surface_t& surface = md3->surfaces[current_surf];
 			sint32         vcount  = surface.header.num_verts;
 			sint32         offset  = vcount * current_frame;
@@ -353,45 +402,9 @@
 				index++;
 			}
-
+			++current_surf;
+			--surf_count;
 		}
 		++current_frame;
 		--frame_count;
-	}
-
-	index = 0;
-	mesh_raw_channel* mc_t = mesh_raw_channel::create< vtx_md3_t >( num_verts );
-	vtx_md3_t* vtx_t = (vtx_md3_t*)mc_t->data;
-	for ( sint32 i = 0; i < num_surfaces; ++i )
-	{
-		const md3_surface_t& surface = md3->surfaces[i];
-		const uint32         vcount  = static_cast< uint32 >( surface.header.num_verts );
-		for (uint32 j = 0; j < vcount; ++j )
-		{
-			vtx_t[index++].texcoord = md3_texcoord( surface.st[j] );
-		}
-	}
-
-	sint32 index_count = 0;
-	for ( sint32 i = 0; i < num_surfaces; ++i )
-	{
-		index_count += md3->surfaces[i].header.num_triangles * 3;
-	}
-
-	index = 0;
-	sint32 index_base = 0;
-	mesh_raw_channel* ic = mesh_raw_channel::create_index< uint16 >( index_count );
-	uint16* icp = (uint16*)ic->data;
-	for ( sint32 i = 0; i < num_surfaces; ++i )
-	{
-		const md3_surface_t& surface = md3->surfaces[i];
-		const size_t         tcount  = static_cast< size_t >( surface.header.num_triangles );
-		for (size_t j = 0; j < tcount; ++j )
-		{
-			const md3_triangle_t& t = surface.triangles[j];
-			icp[index++] = static_cast< uint16 >( index_base + t.indexes[0] );
-			icp[index++] = static_cast< uint16 >( index_base + t.indexes[1] );
-			icp[index++] = static_cast< uint16 >( index_base + t.indexes[2] );
-		}
-		index_base += surface.header.num_verts;
 	}
 
@@ -427,7 +440,24 @@
 mesh_data_pack* nv::md3_loader::release_mesh_data_pack()
 {
-	mesh_data* data = new mesh_data[1];
-	release_mesh_frame( &data[0], -1 );
-	return new mesh_data_pack( 1, data, release_mesh_nodes_data() );
+	md3_t* md3 = (md3_t*)m_md3;
+	uint32 count = 1;
+	mesh_data* data = nullptr;
+	if ( m_merge_all )
+	{
+		data = new mesh_data[1];
+		release_mesh_frame( &data[0], -1, -1 );
+		data[0].set_name( (char*)md3->header.name );
+	}
+	else
+	{
+		count = md3->header.num_surfaces;
+		data = new mesh_data[ count ];
+		for ( uint32 i = 0; i < count; ++i )
+		{
+			release_mesh_frame( &data[i], -1, i );
+			data[i].set_name( (char*)md3->surfaces[i].header.name );
+		}
+	}
+	return new mesh_data_pack( count, data, release_mesh_nodes_data() );
 }
 
