Index: trunk/src/gfx/keyframed_mesh.cc
===================================================================
--- trunk/src/gfx/keyframed_mesh.cc	(revision 228)
+++ trunk/src/gfx/keyframed_mesh.cc	(revision 230)
@@ -15,9 +15,7 @@
 using namespace nv;
 
-keyframed_mesh::keyframed_mesh( context* a_context, mesh_data* a_data, program* a_program )
-	: m_context( a_context )
+keyframed_mesh::keyframed_mesh( context* a_context, mesh_data* a_data )
+	: animated_mesh( a_context )
 	, m_data( a_data )
-	, m_program( a_program )
-	, m_va( nullptr )
 	, m_start_frame( false )
 	, m_stop_frame( false )
@@ -38,8 +36,8 @@
 }
 
-mat4 keyframed_mesh::get_tag( const std::string& tag ) const
-{
-	const std::vector< nv::mat4 >& transforms = m_data->get_tag_map().at( tag );
-	return glm::interpolate( transforms[ m_last_frame ], transforms[ m_next_frame ], m_interpolation );
+transform keyframed_mesh::get_tag( const std::string& tag ) const
+{
+	const std::vector< transform >& transforms = m_data->get_tag_map().at( tag );
+	return interpolate( transforms[ m_last_frame ], transforms[ m_next_frame ], m_interpolation );
 }
 
@@ -101,8 +99,7 @@
 }
 
-void nv::keyframed_mesh::draw( render_state& rstate )
-{
-	m_program->set_opt_uniform( "nv_interpolate", m_interpolation );
-	m_context->draw( nv::TRIANGLES, rstate, m_program, m_va, m_data->get_index_count() );
+void nv::keyframed_mesh::update( program* a_program )
+{
+	a_program->set_opt_uniform( "nv_interpolate", m_interpolation );
 }
 
@@ -112,6 +109,12 @@
 }
 
+void nv::keyframed_mesh::run_animation( animation_entry* a_anim )
+{
+	keyframed_animation_entry * anim = down_cast<keyframed_animation_entry>(a_anim);
+	setup_animation( anim->m_start, anim->m_frames, anim->m_fps, anim->m_looping );
+}
+
 keyframed_mesh_gpu::keyframed_mesh_gpu( context* a_context, mesh_data* a_data, program* a_program )
-	: keyframed_mesh( a_context, a_data, a_program )
+	: keyframed_mesh( a_context, a_data )
 	, m_loc_next_position( 0 )
 	, m_loc_next_normal( 0 )
@@ -120,6 +123,6 @@
 {
 	nv::vertex_buffer* vb;
-	m_loc_next_position = m_program->get_attribute( "nv_next_position" )->get_location();
-	m_loc_next_normal   = m_program->get_attribute( "nv_next_normal" )->get_location();
+	m_loc_next_position = a_program->get_attribute( "nv_next_position" )->get_location();
+	m_loc_next_normal   = a_program->get_attribute( "nv_next_normal" )->get_location();
 
 	vb = m_context->get_device()->create_vertex_buffer( nv::STATIC_DRAW, m_data->get_vertex_count() * sizeof( nv::vec3 ) * m_data->get_frame_count(), (void*)m_data->get_positions().data() );
@@ -137,6 +140,8 @@
 }
 
-void nv::keyframed_mesh_gpu::draw( render_state& rstate )
-{
+void nv::keyframed_mesh_gpu::update( uint32 ms )
+{
+	keyframed_mesh::update( ms );
+
 	size_t vtx_count = m_data->get_vertex_count();
 	if ( m_gpu_last_frame != m_last_frame )
@@ -152,10 +157,9 @@
 		m_gpu_next_frame = m_next_frame;
 	}
-	keyframed_mesh::draw( rstate );
-}
-
-
-nv::keyframed_mesh_cpu::keyframed_mesh_cpu( context* a_context, mesh_data* a_data, program* a_program )
-	: keyframed_mesh( a_context, a_data, a_program )
+}
+
+
+nv::keyframed_mesh_cpu::keyframed_mesh_cpu( context* a_context, mesh_data* a_data )
+	: keyframed_mesh( a_context, a_data )
 {
 	m_vb_position = m_context->get_device()->create_vertex_buffer( nv::STATIC_DRAW, m_data->get_vertex_count() * sizeof( nv::vec3 ), (void*)m_data->get_position_frame(0) );
Index: trunk/src/gfx/skeletal_mesh.cc
===================================================================
--- trunk/src/gfx/skeletal_mesh.cc	(revision 228)
+++ trunk/src/gfx/skeletal_mesh.cc	(revision 230)
@@ -11,8 +11,6 @@
 
 
-nv::skeletal_mesh::skeletal_mesh( context* a_context, program* a_program, md5_loader* a_loader )
-	: m_context( a_context )
-	, m_program( a_program )
-	, m_va( nullptr )
+nv::skeletal_mesh::skeletal_mesh( context* a_context, md5_loader* a_loader )
+	: animated_mesh( a_context )
 	, m_data( a_loader )
 	, m_animation( nullptr )
@@ -38,4 +36,5 @@
 	if ( m_animation ) m_animation->reset_animation();
 	m_animation = a_anim;
+	// TODO : INSTANCE!
 	m_animation->reset_animation();
 }
@@ -64,11 +63,13 @@
 }
 
-void nv::skeletal_mesh::draw( render_state& rstate )
-{
-	m_context->draw( nv::TRIANGLES, rstate, m_program, m_va, m_data->get_index_count(0) );
-}
-
 nv::skeletal_mesh::~skeletal_mesh()
 {
 	delete m_va;
 }
+
+void nv::skeletal_mesh::run_animation( animation_entry* a_anim )
+{
+	skeletal_animation_entry * anim = down_cast<skeletal_animation_entry>(a_anim);
+	// TODO : INSTANCE!
+	setup_animation( anim->m_animation );
+}
