Index: trunk/src/gfx/keyframed_mesh.cc
===================================================================
--- trunk/src/gfx/keyframed_mesh.cc	(revision 240)
+++ trunk/src/gfx/keyframed_mesh.cc	(revision 241)
@@ -44,7 +44,7 @@
 {
 	NV_ASSERT( m_tag_map, "TAGMAP FAIL" );
-	const std::vector< transform >* transforms = m_tag_map->get_tag( tag );
+	const transform_vector* transforms = m_tag_map->get_tag( tag );
 	NV_ASSERT( transforms, "TAG FAIL" );
-	return interpolate( (*transforms)[ m_last_frame ], (*transforms)[ m_next_frame ], m_interpolation );
+	return interpolate( transforms->get( m_last_frame ), transforms->get( m_next_frame ), m_interpolation  );
 }
 
Index: trunk/src/gfx/skeletal_mesh.cc
===================================================================
--- trunk/src/gfx/skeletal_mesh.cc	(revision 240)
+++ trunk/src/gfx/skeletal_mesh.cc	(revision 241)
@@ -13,8 +13,10 @@
 nv::skeletal_mesh::skeletal_mesh( context* a_context, md5_mesh_data* a_mesh_data )
 	: animated_mesh()
-	, m_mesh_data( a_mesh_data )
+	, m_mesh_data( nullptr )
 	, m_animation( nullptr )
+	, m_animation_time( 0 )
 {
-	m_va = a_context->get_device()->create_vertex_array( a_mesh_data, nv::STREAM_DRAW );
+	m_mesh_data = a_mesh_data->spawn();
+	m_va        = a_context->get_device()->create_vertex_array( a_mesh_data, nv::STREAM_DRAW );
 }
 
@@ -22,20 +24,26 @@
 void nv::skeletal_mesh::setup_animation( md5_animation* a_anim )
 {
-	if ( m_animation ) m_animation->reset_animation();
-	m_animation = a_anim;
-	// TODO : INSTANCE!
-	m_animation->reset_animation();
+	m_animation      = a_anim;
+	m_animation_time = 0;
+	if ( m_animation )
+	{
+		m_transform.resize( m_animation->get_num_joints() );
+		update( 0 );
+	}
 }
 
 void nv::skeletal_mesh::update( uint32 ms )
 {
-	if (m_animation != nullptr)
+	if ( m_animation )
 	{
-		m_animation->update( ms * 0.001f );
-		m_mesh_data->apply( *m_animation );
+		m_animation_time += ms;
+		float frame_duration = 1000.f / (float)m_animation->get_frame_rate();
+		uint32 anim_duration = uint32( frame_duration * (float)m_animation->get_frame_count() );
+		while ( m_animation_time >= anim_duration ) m_animation_time -= anim_duration;
+		m_animation->update_skeleton( m_transform, (float)m_animation_time * 0.001f );
+		m_mesh_data->apply( m_transform );
 		vertex_buffer* vb = m_va->find_buffer( nv::POSITION );
-		const mesh_raw_channel* pch = m_mesh_data->get_channel_data()[0];
 		vb->bind();
-		vb->update( (const void*)pch->data, 0, pch->size );
+		vb->update( m_mesh_data->data(), 0, m_mesh_data->size() );
 		vb->unbind();
 	}
@@ -45,6 +53,5 @@
 {
 	delete m_va;
-	// TODO : INSTANCE!
-	//	delete m_mesh_data;
+	delete m_mesh_data;
 }
 
@@ -52,5 +59,4 @@
 {
 	skeletal_animation_entry * anim = down_cast<skeletal_animation_entry>(a_anim);
-	// TODO : INSTANCE!
 	setup_animation( anim->m_animation );
 }
