Index: trunk/src/gfx/keyframed_mesh.cc
===================================================================
--- trunk/src/gfx/keyframed_mesh.cc	(revision 479)
+++ 	(revision )
@@ -1,248 +1,0 @@
-// Copyright (C) 2011-2015 ChaosForge Ltd
-// http://chaosforge.org/
-//
-// This file is part of Nova libraries. 
-// For conditions of distribution and use, see copying.txt file in root folder.
-
-#include "nv/gfx/keyframed_mesh.hh"
-
-#include "nv/interface/context.hh"
-#include "nv/interface/device.hh"
-#include "nv/core/logging.hh"
-
-using namespace nv;
-
-nv::keyframed_mesh::keyframed_mesh( context* a_context, const data_channel_set* a_data, const mesh_nodes_data* a_tag_map )
-	: animated_mesh()
-	, m_context( a_context )
-	, m_tag_map( a_tag_map )
-	, m_last_frame( 0 )
-	, m_next_frame( 0 )
-	, m_interpolation( 0.0f )
-	, m_active( false )
-{
-	m_index_count   = a_data->get_channel_size( slot::INDEX );
-	m_vertex_count  = a_data->get_channel_size<vertex_t>();
-	uint32 pos_size = a_data->get_channel_size<vertex_pnt>();
-	if ( pos_size == 0 )
-	{
-		pos_size      = a_data->get_channel_size<vertex_pn>();
-		m_has_tangent = false;
-		m_vsize       = sizeof( vertex_pn );
-	}
-	else
-	{
-		m_has_tangent = true;
-		m_vsize       = sizeof( vertex_pnt );
-	}
-	m_frame_count  = pos_size / m_vertex_count;
-	m_pbuffer      = buffer();
-
-	if ( m_tag_map && m_tag_map->size() > 0 )
-	{
-		m_interpolation_key = (*m_tag_map)[ 0 ]->get_interpolation_key();
-	}
-}
-
-nv::size_t keyframed_mesh::get_max_frames() const
-{
-	return m_frame_count;
-}
-
-transform keyframed_mesh::get_node_transform( uint32 node_id ) const
-{
-	if ( !m_tag_map ) return transform();
-	NV_ASSERT( node_id < m_tag_map->size(), "TAGMAP FAIL" );
-	NV_ASSERT( (*m_tag_map)[node_id]->size() > 0, "TAG FAIL" );
-	raw_channel_interpolator interpolator( ( *m_tag_map )[node_id], m_interpolation_key );
-	return interpolator.get< transform >( m_last_frame, m_next_frame, m_interpolation );
-}
-
-mat4 keyframed_mesh::get_node_matrix( uint32 node_id ) const
-{
-	return get_node_transform( node_id ).extract();
-}
-
-void nv::keyframed_mesh::set_frame( uint32 frame )
-{
-	m_last_frame    = frame;
-	m_next_frame    = frame;
-	m_active        = false;
-	m_interpolation = 0.0f;
-}
-
-void nv::keyframed_mesh::update_animation( animation_entry* anim, uint32 a_ms_anim_time )
-{
-	if ( m_active )
-	{
-		float  fframe   = ( static_cast<float>( a_ms_anim_time ) * 0.001f ) * anim->get_fps();
-		uint32 frame    = uint32( fframe );
-		float  reminder = fframe - static_cast<float>( frame );
-		uint32 duration = anim->is_looping() ? anim->get_frame_count() + 1 : anim->get_frame_count();
-
-		if ( frame >= duration )
-		{
-			if ( anim->is_looping() )
-			{
-				frame  = frame % duration;
-				fframe = static_cast<float>( frame ) + reminder;
-			}
-			else
-			{
-				m_active        = false;
-				m_last_frame    = anim->get_end_frame();
-				m_next_frame    = m_last_frame;
-				m_interpolation = 0.0f;
-				return;
-			}
-		}
-		m_last_frame    = frame + anim->get_start_frame();
-		m_next_frame    = m_last_frame + 1;
-		if ( m_next_frame > anim->get_end_frame() ) m_next_frame = anim->get_start_frame();
-		m_interpolation = reminder;
-	}
-}
-
-
-void nv::keyframed_mesh::update( program a_program )
-{
-	m_context->get_device()->set_opt_uniform( a_program, "nv_interpolate", m_interpolation );
-}
-
-nv::keyframed_mesh::~keyframed_mesh()
-{
-	m_context->release( m_va );
-}
-
-void nv::keyframed_mesh::run_animation( animation_entry* a_anim )
-{
-	if ( a_anim )
-	{
-		m_active        = true;
-		m_last_frame    = 0;
-		m_next_frame    = 0;
-		m_interpolation = 0.0f;
-	}
-	else
-	{
-		m_active = false;
-	}
-}
-
-nv::keyframed_mesh_gpu::keyframed_mesh_gpu( context* a_context, const data_channel_set* a_data, const mesh_nodes_data* a_tag_map )
-	: keyframed_mesh( a_context, a_data, a_tag_map )
-	, m_loc_next_position( -1 )
-	, m_loc_next_normal( -1 )
-	, m_loc_next_tangent( -1 )
-	, m_gpu_last_frame( 0xFFFFFFFF )
-	, m_gpu_next_frame( 0xFFFFFFFF )
-{
-	m_va      = a_context->create_vertex_array( a_data, STATIC_DRAW );
-	m_pbuffer = a_context->find_buffer( m_va, slot::POSITION );
-}
-
-
-void nv::keyframed_mesh_gpu::update_animation( animation_entry* anim, uint32 a_anim_time )
-{
-	keyframed_mesh::update_animation( anim, a_anim_time );
-	if ( m_loc_next_position == -1 ) return;
-	if ( m_gpu_last_frame != m_last_frame )
-	{
-		uint32 base_offset = m_last_frame * m_vertex_count * m_vsize; 
-		m_context->update_attribute_offset( m_va, slot::POSITION, base_offset );
-		m_context->update_attribute_offset( m_va, slot::NORMAL,   base_offset + sizeof( vec3 ) );
-		if ( m_has_tangent && m_loc_next_tangent != -1 )
-		{
-			m_context->update_attribute_offset( m_va, slot::TANGENT, base_offset + 2*sizeof( vec3 ) );
-		}
-		m_gpu_last_frame = m_last_frame;
-	}
-	if ( m_loc_next_position != -1 && m_gpu_next_frame != m_next_frame )
-	{
-		uint32 base_offset = m_next_frame * m_vertex_count * m_vsize; 
-		m_context->update_attribute_offset( m_va, static_cast<slot>( m_loc_next_position ), base_offset );
-		m_context->update_attribute_offset( m_va, static_cast<slot>( m_loc_next_normal ), base_offset + sizeof( vec3 ) );
-		if ( m_has_tangent && m_loc_next_tangent != -1 )
-		{
-			m_context->update_attribute_offset( m_va, static_cast<slot>( m_loc_next_tangent ), base_offset + 2*sizeof( vec3 ) );
-		}
-		m_gpu_next_frame = m_next_frame;
-	}
-}
-
-void nv::keyframed_mesh_gpu::update( program a_program )
-{
-	if ( m_loc_next_position == -1 )
-	{
-		device* dev = m_context->get_device();
-		m_loc_next_position = dev->get_attribute_location( a_program, "nv_next_position" );
-		m_loc_next_normal   = dev->get_attribute_location( a_program, "nv_next_normal" );
-		if ( m_has_tangent )
-			m_loc_next_tangent  = dev->get_attribute_location( a_program, "nv_next_tangent" );
-
-		m_context->add_vertex_buffer( m_va, static_cast<slot>( m_loc_next_position ), m_pbuffer, FLOAT, 3, 0, m_vsize, false );
-		m_context->add_vertex_buffer( m_va, static_cast<slot>( m_loc_next_normal ),   m_pbuffer, FLOAT, 3, sizeof( vec3 ), m_vsize, false );
-		if ( m_has_tangent )
-			m_context->add_vertex_buffer( m_va, static_cast<slot>( m_loc_next_tangent ), m_pbuffer, FLOAT, 4, 2*sizeof( vec3 ), m_vsize, false );
-	}
-	keyframed_mesh::update( a_program );
-}
-
-nv::keyframed_mesh_cpu::keyframed_mesh_cpu( context* a_context, const data_channel_set* a_data, const mesh_nodes_data* a_tag_map )
-	: keyframed_mesh( a_context, a_data, a_tag_map )
-{
-	const raw_data_channel* vchannel = m_has_tangent ? a_data->get_channel< vertex_pnt >() : a_data->get_channel< vertex_pn >();
-	m_va      = m_context->create_vertex_array();
-	m_pbuffer = m_context->get_device()->create_buffer( VERTEX_BUFFER, STATIC_DRAW, m_vertex_count * m_vsize, vchannel->raw_data() );
-	m_context->add_vertex_buffers( m_va, m_pbuffer, vchannel->descriptor() );
-
-	buffer  vb = m_context->get_device()->create_buffer( VERTEX_BUFFER, STATIC_DRAW, m_vertex_count * sizeof( vec2 ), a_data->get_channel_data<vertex_t>() );
-	m_context->add_vertex_buffers( m_va, vb, a_data->get_channel<vertex_t>()->descriptor() );
-
-	const raw_data_channel* index_channel = a_data->get_channel( slot::INDEX );
-	buffer  ib = m_context->get_device()->create_buffer( INDEX_BUFFER, STATIC_DRAW, index_channel->raw_size(), index_channel->raw_data() );
-	m_context->set_index_buffer( m_va, ib, index_channel->descriptor()[0].etype, true );
-
-	m_data = new uint8[ m_vertex_count * m_vsize ];
-
-	m_model_data = vchannel->raw_data();
-}
-
-void nv::keyframed_mesh_cpu::update_animation( animation_entry* anim, uint32 a_anim_time )
-{
-	keyframed_mesh::update_animation( anim, a_anim_time );
-	// TODO: this could be done generic for any data
-	if ( m_has_tangent )
-	{
-		const vertex_pnt* data = reinterpret_cast< const vertex_pnt* >( m_model_data );
-		const vertex_pnt* prev = data + m_vertex_count * m_last_frame;
-		const vertex_pnt* next = data + m_vertex_count * m_next_frame;
-		      vertex_pnt* vtx  = reinterpret_cast<vertex_pnt*>( m_data );
-		for ( size_t i = 0; i < m_vertex_count; ++i )
-		{
-			vtx[i].position = math::mix( prev[i].position, next[i].position, m_interpolation );
-			vtx[i].normal   = math::mix( prev[i].normal,   next[i].normal,   m_interpolation );
-			vtx[i].tangent  = math::mix( prev[i].tangent,  next[i].tangent,   m_interpolation );
-		}
-	}
-	else
-	{
-		const vertex_pn* data = reinterpret_cast< const vertex_pn* >( m_model_data );
-		const vertex_pn* prev = data + m_vertex_count * m_last_frame;
-		const vertex_pn* next = data + m_vertex_count * m_next_frame;
-		      vertex_pn* vtx  = reinterpret_cast<vertex_pn*>( m_data );
-
-		for ( size_t i = 0; i < m_vertex_count; ++i )
-		{
-			vtx[i].position = math::mix( prev[i].position, next[i].position, m_interpolation );
-			vtx[i].normal   = math::mix( prev[i].normal,   next[i].normal,   m_interpolation );
-		}
-	}
-
-	m_context->update( m_pbuffer, m_data, 0, m_vertex_count * m_vsize );
-}
-
-nv::keyframed_mesh_cpu::~keyframed_mesh_cpu()
-{
-	delete[] m_data;
-}
Index: trunk/src/gfx/mesh_creator.cc
===================================================================
--- trunk/src/gfx/mesh_creator.cc	(revision 479)
+++ trunk/src/gfx/mesh_creator.cc	(revision 480)
@@ -157,9 +157,4 @@
 		}
 	}
-}
-
-nv::mesh_data_creator::mesh_data_creator( data_channel_set* data ) : m_data( data )
-{
-	initialize();
 }
 
@@ -656,11 +651,2 @@
 }
 
-void nv::mesh_creator::delete_mesh( uint32 index )
-{
-	if ( index < m_pack->get_count() )
-	{
-
-		m_pack->m_meshes[index] = move( m_pack->m_meshes[m_pack->m_count - 1] );
-		m_pack->m_count--;
-	}
-}
Index: trunk/src/gfx/skeletal_mesh.cc
===================================================================
--- trunk/src/gfx/skeletal_mesh.cc	(revision 479)
+++ 	(revision )
@@ -1,73 +1,0 @@
-// Copyright (C) 2011-2015 ChaosForge Ltd
-// http://chaosforge.org/
-//
-// This file is part of Nova libraries. 
-// For conditions of distribution and use, see copying.txt file in root folder.
-
-#include "nv/gfx/skeletal_mesh.hh"
-
-#include "nv/interface/context.hh"
-#include "nv/interface/device.hh"
-#include "nv/stl/unordered_map.hh"
-
-#include "nv/core/logging.hh"
-
-void nv::skeletal_animation_entry::update_skeleton( skeleton_instance& data, uint32 a_ms_time ) const
-{
-	float  fframe = ( a_ms_time * 0.001f ) * m_fps;
-	float  nframe = nv::floor( fframe );
-	uint32 duration = get_frame_count();
-	if ( duration == 0 )
-	{
-		fframe = static_cast<float>( get_start_frame() );
-	}
-	else if ( nframe >= duration )
-	{
-		if ( is_looping() )
-			fframe = nv::fmodf( fframe, nv::f32( duration ) );
-		else
-			fframe = static_cast<float>( get_end_frame() );
-	}
-
-	if ( data.size() == 0 )
-		data.initialize( m_temp_anim->size() );
-	data.animate( m_temp_anim, m_data, fframe );
-}
-
-void nv::skeletal_animation_entry::prepare( const mesh_nodes_data* bones )
-{
-	m_data.prepare( m_temp_anim, bones ? bones : m_temp_anim );
-}
-
-nv::skeletal_mesh::skeletal_mesh( context* a_context, const data_channel_set* a_mesh, const mesh_nodes_data* a_bone_data )
-	: m_skeleton( a_bone_data ? a_bone_data->size() : 0 ), m_context( a_context ), m_bone_data( a_bone_data ), m_index_count( 0 ), m_parent_id(-1)
-{
-	if ( a_mesh )
-	{
-		m_va = a_context->create_vertex_array( a_mesh, nv::STATIC_DRAW );
-		m_index_count = a_mesh->get_channel_size( slot::INDEX );
-		m_parent_id = a_mesh->get_parent_id();
-	}
-}
-
-void nv::skeletal_mesh::update_animation( animation_entry& a_anim, uint32 a_anim_time )
-{
-	skeletal_animation_entry& anim = static_cast<skeletal_animation_entry&>( a_anim );
-	anim.prepare( m_bone_data );
-	anim.update_skeleton( m_skeleton, a_anim_time );
-}
-
-void nv::skeletal_mesh::update_program( program a_program )
-{
-	m_context->get_device()->set_opt_uniform_array( a_program, "nv_m_bones", m_skeleton.transforms(), m_skeleton.size() );
-}
-
-nv::transform nv::skeletal_mesh::get_node_transform( uint32 node_id ) const
-{
-	return transform( get_node_matrix( node_id ) );
-}
-
-nv::mat4 nv::skeletal_mesh::get_node_matrix( uint32 node_id ) const
-{
-	return m_skeleton.transforms()[ node_id ];
-}
Index: trunk/src/gfx/skeleton_instance.cc
===================================================================
--- trunk/src/gfx/skeleton_instance.cc	(revision 479)
+++ trunk/src/gfx/skeleton_instance.cc	(revision 480)
@@ -6,4 +6,6 @@
 
 #include "nv/gfx/skeleton_instance.hh"
+
+#include "nv/core/profiler.hh"
 
 void nv::skeleton_binding::prepare( const mesh_nodes_data* node_data, const mesh_nodes_data* bone_data )
@@ -62,28 +64,28 @@
 			for ( uint32 n = 0; n < node_data->size(); ++n )
 				if ( ( *node_data )[n]->get_parent_id() == -1 )
-					animate_rec( node_data, binding, frame, n, mat4() );
+					animate_rec( node_data, binding, frame, n, transform() );
 		}
 	}
 }
 
-void nv::skeleton_instance::animate_rec( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame, uint32 id, const mat4& parent ) 
+void nv::skeleton_instance::animate_rec( const mesh_nodes_data* node_data, const skeleton_binding& binding, float frame, uint32 id, const transform& parent )
 {
 	// TODO: fix transforms, which are now embedded,
 	//       see note in assimp_loader.cc:load_node
 	const data_channel_set* node = ( *node_data )[id];
-	mat4 node_mat( node->get_transform() );
+	transform node_mat( node->get_transform() );
 
 	if ( node->size() > 0 )
 	{
 		raw_channel_interpolator interpolator( node, binding.m_key );
-		node_mat = interpolator.get< mat4 >( frame );
+		node_mat = interpolator.get< transform >( frame );
 	}
 
-	mat4 global_mat = parent * node_mat;
+	transform global_mat = parent * node_mat;
 
 	sint16 bone_id = binding.m_indices[id];
 	if ( bone_id >= 0 )
 	{
-		m_transform[bone_id] = global_mat * binding.m_offsets[bone_id];
+		m_transform[bone_id] = global_mat.extract() * binding.m_offsets[bone_id];
 	}
 
