Index: trunk/src/formats/nmd_loader.cc
===================================================================
--- trunk/src/formats/nmd_loader.cc	(revision 482)
+++ trunk/src/formats/nmd_loader.cc	(revision 485)
@@ -26,6 +26,7 @@
 		{
 		case nmd_type::MESH           : load_mesh( source, element_header ); break;
-		case nmd_type::ANIMATION      : load_animation( source, element_header ); break;
+		case nmd_type::BONES          : load_bones( source, element_header ); break;
 		case nmd_type::STRINGS        : load_strings( source ); break;
+		case nmd_type::POSES          : load_poses( source, element_header ); break;
 		default: NV_ASSERT( false, "UNKNOWN NMD ELEMENT!" ); break;
 		}
@@ -39,5 +40,4 @@
 	data_node_info info;
 	load_channel_set( source, mesh, info, e );
-//	m_mesh_names.push_back( e.name );
 	m_infos.push_back( info );
 	m_meshes.push_back( mesh );
@@ -56,9 +56,8 @@
 {
 	for ( auto mesh : m_meshes ) if ( mesh ) delete mesh;
-	if ( m_node_data ) delete m_node_data;
 	if ( m_bone_data ) delete m_bone_data;
+	if ( m_pose_data_set ) delete m_pose_data_set;
 	m_meshes.clear();
 
-	m_node_data = nullptr;
 	m_bone_data = nullptr;
 }
@@ -85,10 +84,9 @@
 }
 
-bool nv::nmd_loader::load_animation( stream& source, const nmd_element_header& e )
-{
-	NV_ASSERT( m_node_data == nullptr, "MULTIPLE NODE ENTRIES!" );
+bool nv::nmd_loader::load_bones( stream& source, const nmd_element_header& e )
+{
+	NV_ASSERT( m_bone_data == nullptr, "MULTIPLE NODE ENTRIES!" );
 	nmd_animation_header animation_header;
 	source.read( &animation_header, sizeof( animation_header ), 1 );
-	m_node_data = new mesh_nodes_data( e.name, animation_header.frame_rate, animation_header.frame_count );
 	m_bone_data = new data_node_list( e.name );
 	for ( uint32 i = 0; i < e.children; ++i )
@@ -102,7 +100,6 @@
 		load_channel_set( source, set, info, element_header );
 		m_bone_data->append( info );
-		m_node_data->append( set, info );
-	}
-	m_node_data->initialize();
+		delete set;
+	}
 	return true;
 }
@@ -131,9 +128,37 @@
 }
 
+bool nv::nmd_loader::load_poses( stream& source, const nmd_element_header& e )
+{
+	if ( m_pose_data_set == nullptr )
+	{
+		NV_ASSERT_ALWAYS( m_bone_data, "POSES WITHOUT BONES!" );
+		m_pose_data_set = new pose_data_set;
+		m_pose_data_set->initialize( *m_bone_data );
+	}
+
+	uint32  count = e.children;
+	shash64 name  = e.name;
+
+	auto& set = m_pose_data_set->m_sets[ name ];
+	NV_ASSERT_ALWAYS( !set.name, "SET REWRITE!" );
+	set.name = name;
+	set.count = count;
+	set.start = m_pose_data_set->size();
+
+	for ( uint32 i = 0; i < count; ++i )
+	{
+		uint32 length = 0; 
+		source.read( &length, sizeof( length ), 1 );
+		m_pose_data_set->m_data.push_back( skeleton_transforms() );
+		auto& data = m_pose_data_set->m_data.back().m_transforms;
+		data.resize( length );
+		source.read( &data[0], length * sizeof( transform ), 1 );
+	}
+	return true;
+}
+
 mesh_nodes_data* nv::nmd_loader::release_mesh_nodes_data( size_t )
 {
-	mesh_nodes_data* result = m_node_data;
-	m_node_data = nullptr;
-	return result;
+	return nullptr;
 }
 
@@ -147,6 +172,5 @@
 bool nv::nmd_loader::is_animated( size_t /*= 0 */ )
 {
-	if ( !m_node_data ) return false;
-	return m_node_data->is_animated();
+	return m_pose_data_set != nullptr;
 }
 
@@ -194,5 +218,5 @@
 }
 
-void nv::nmd_dump_nodes( stream& stream_out, const mesh_nodes_data& nodes )
+void nv::nmd_dump_bones( stream& stream_out, const data_node_list& nodes )
 {
 	uint32 total = sizeof( nmd_animation_header );
@@ -200,44 +224,8 @@
 	{
 		total += sizeof( nmd_element_header );
-		for ( uint32 c = 0; c < node->size(); ++c )
-		{
-			total += sizeof( nmd_channel_header );
-			total += node->get_channel( c )->raw_size();
-		}
 	}
 
 	nmd_element_header header;
-	header.type = nmd_type::ANIMATION;
-	header.children = static_cast<uint16>( nodes.size() );
-	header.size = total;
-	header.name = nodes.get_name();
-	header.transform = mat4();
-	header.parent_id = -1;
-	header.attributes = 0;
-
-	stream_out.write( &header, sizeof( header ), 1 );
-
-	nmd_animation_header aheader;
-	aheader.frame_rate  = nodes.get_fps();
-	aheader.frame_count = nodes.get_frame_count();
-	aheader.unused      = false;
-	stream_out.write( &aheader, sizeof( aheader ), 1 );
-
-	for ( uint32 i = 0; i < nodes.size(); ++i )
-	{
-		nmd_dump_element( stream_out, *nodes[i], nodes.get_info(i), nv::nmd_type::NODE );
-	}
-}
-
-void nv::nmd_dump_bones( stream& stream_out, const data_node_list& nodes )
-{
-	uint32 total = sizeof( nmd_animation_header );
-	for ( auto node : nodes )
-	{
-		total += sizeof( nmd_element_header );
-	}
-
-	nmd_element_header header;
-	header.type = nmd_type::ANIMATION;
+	header.type = nmd_type::BONES;
 	header.children = static_cast<uint16>( nodes.size() );
 	header.size = total;
@@ -269,4 +257,38 @@
 }
 
+void nv::nmd_dump_poses( stream& stream_out, const array_view< skeleton_transforms* > poses, shash64 name )
+{
+	nmd_element_header pheader;
+	pheader.type       = nv::nmd_type::POSES;
+	pheader.children   = poses.size();
+	pheader.size       = sizeof( transform ) * poses.size() * ( poses.size() > 0 ? poses[0]->size() : 0 )
+		               + sizeof( uint32 ) * poses.size();
+	pheader.name       = name;
+	pheader.parent_id  = -1;
+	pheader.attributes = 0;
+	stream_out.write( &pheader, sizeof( pheader ), 1 );
+	for ( auto pose : poses )
+	{
+		uint32 count = pose->size();
+		stream_out.write( &count, sizeof( count ), 1 );
+		stream_out.write( pose->xforms(), sizeof( transform ) * count, 1 );
+	}
+}
+
+void nv::nmd_dump_pose( stream& stream_out, const skeleton_transforms& pose, shash64 name )
+{
+	nmd_element_header pheader;
+	pheader.type       = nv::nmd_type::POSES;
+	pheader.children   = 1;
+	pheader.size       = sizeof( transform ) * pose.size();
+	pheader.name       = name;
+	pheader.parent_id  = -1;
+	pheader.attributes = 0;
+	stream_out.write( &pheader, sizeof( pheader ), 1 );
+	uint32 count = pose.size();
+	stream_out.write( &count, sizeof( count ), 1 );
+	stream_out.write( pose.xforms(), sizeof( transform ) * count, 1 );
+}
+
 void nv::nmd_dump_strings( stream& stream_out, const string_table& strings )
 {
@@ -282,5 +304,5 @@
 }
 
-void nv::nmd_dump( stream& stream_out, array_view< data_channel_set* > meshes, array_view< data_node_info > infos, const mesh_nodes_data* nodes, const string_table* strings /*= nullptr*/, uint64 name /*= 0 */ )
+void nv::nmd_dump( stream& stream_out, array_view< data_channel_set* > meshes, array_view< data_node_info > infos, const nv::data_node_list* nodes, const string_table* strings /*= nullptr*/, uint64 name /*= 0 */ )
 {
 	uint32 elements = ( strings ? 1 : 0 ) // +1 string array
@@ -297,5 +319,5 @@
 	if ( nodes && nodes->size() > 0 )
 	{
-		nmd_dump_nodes( stream_out, *nodes );
+		nmd_dump_bones( stream_out, *nodes );
 	}
 
@@ -305,43 +327,2 @@
 	}
 }
-
-void nv::nmd_dump( stream& stream_out, array_view< data_channel_set* > meshes, array_view< data_node_info > infos, const nv::data_node_list* nodes, const string_table* strings /*= nullptr*/, uint64 name /*= 0 */ )
-{
-	uint32 elements = ( strings ? 1 : 0 ) // +1 string array
-		+ meshes.size() // meshes
-		+ ( nodes && nodes->size() > 0 ? 1 : 0 ); // nodes
-	nmd_dump_header( stream_out, elements, name );
-
-	for ( uint32 i = 0; i < meshes.size(); ++i )
-	{
-		NV_ASSERT( meshes[i], "mesh is null!" );
-		nmd_dump_element( stream_out, *meshes[i], infos[i], nv::nmd_type::MESH );
-	}
-
-	if ( nodes && nodes->size() > 0 )
-	{
-		nmd_dump_bones( stream_out, *nodes );
-	}
-
-	if ( strings )
-	{
-		nmd_dump_strings( stream_out, *strings );
-	}
-}
-
-void nv::nmd_dump( stream& stream_out, const mesh_nodes_data& animation, const string_table* strings, uint64 name )
-{
-	uint32 elements = ( strings ? 1 : 0 ) // +1 string array
-		+ ( animation.size() > 0 ? 1 : 0 ); // nodes
-	nmd_dump_header( stream_out, elements, name );
-
-	if ( animation.size() > 0 )
-	{
-		nmd_dump_nodes( stream_out, animation );
-	}
-
-	if ( strings )
-	{
-		nmd_dump_strings( stream_out, *strings );
-	}
-}
