Index: trunk/src/gfx/debug_draw.cc
===================================================================
--- trunk/src/gfx/debug_draw.cc	(revision 514)
+++ trunk/src/gfx/debug_draw.cc	(revision 520)
@@ -101,4 +101,47 @@
 }
 
+void nv::debug_data::push_wire_capsule( const transform& tr, float radius, float height )
+{
+	vec3 p = tr.get_position();
+	quat o = tr.get_orientation();
+	vec3 dir   = o * vec3( 0, 1, 0 );
+	vec3 ldir  = o * vec3( 1, 0, 0 );
+	vec3 h1dir = o * normalize( vec3( 1, -1, 0 ) );
+	vec3 h2dir = o * normalize( vec3( 1, 1, 0 ) );
+	vec3 sp1[12];
+	vec3 sp2[12];
+	vec3 hsp1[12];
+	vec3 hsp2[12];
+	for ( uint32 i = 0; i < 12; ++i )
+	{
+		sp1[i]  = nv::math::rotate( ldir * radius, ( float( i ) / 12.0f ) * math::two_pi<float>(), dir );
+		hsp1[i] = nv::math::rotate( h1dir * radius, ( float( i ) / 12.0f ) * math::two_pi<float>(), dir );
+	}
+	for ( uint32 i = 0; i < 12; ++i )
+	{
+		sp2[i]  = nv::math::rotate( ldir * radius + height * dir, ( float( i ) / 12.0f ) * math::two_pi<float>(), dir );
+		hsp2[i] = nv::math::rotate( h2dir * radius + height * dir, ( float( i ) / 12.0f ) * math::two_pi<float>(), dir );
+	}
+
+	for ( uint32 i = 0; i < 12; ++i )
+	{
+		push_line( p + sp1[i], p + sp1[( i + 1 ) % 12], vec3( 1.0f, 0.0f, 0.0f ) );
+		push_line( p + sp2[i], p + sp2[( i + 1 ) % 12], vec3( 0.0f, 1.0f, 0.0f ) );
+		push_line( p + sp1[i], p + sp2[i], vec3( 0.0f, 0.0f, 1.0f ) );
+
+		push_line( p + hsp1[i], p + sp1[i], vec3( 0.0f, 0.0f, 1.0f ) );
+		push_line( p + hsp1[i], p + hsp1[( i + 1 ) % 12], vec3( 1.0f, 0.0f, 0.0f ) );
+		push_line( p + hsp2[i], p + sp2[i], vec3( 0.0f, 0.0f, 1.0f ) );
+		push_line( p + hsp2[i], p + hsp2[( i + 1 ) % 12], vec3( 0.0f, 1.0f, 0.0f ) );
+
+		push_line( p + hsp1[i], p - radius * dir, vec3( 0.0f, 0.0f, 1.0f ) );
+		push_line( p + hsp2[i], p + ( height + radius ) * dir, vec3( 0.0f, 0.0f, 1.0f ) );
+
+	}
+
+		
+}
+
+
 nv::debug_data::~debug_data()
 {
Index: trunk/src/gfx/gfx_terminal.cc
===================================================================
--- trunk/src/gfx/gfx_terminal.cc	(revision 514)
+++ trunk/src/gfx/gfx_terminal.cc	(revision 520)
@@ -84,7 +84,5 @@
 		fgcolor = fg.get_argb32();
 		bgcolor = bg.get_argb32();
-		gylph   = uint32( ch );
-		NV_LOG_INFO( uint32( 
-			( fgcolor & uint32( 0x00FF0000 ) ) >> 16 ), "-", uint32( ( fgcolor & uint32( 0x0000FF00 ) ) >> 8 ),"-" , uint32( fgcolor & uint32( 0x000000FF ) ) );
+		gylph   = uint32( uint8(ch) );
 	}
 };
@@ -139,5 +137,5 @@
 	m_dc.p = m_context->create_program( nv_gfx_terminal_vs, nv_gfx_terminal_fs );
 
-	m_data->buffer = m_context->create_buffer( nv::UNIFORM_BUFFER, nv::DYNAMIC_DRAW, tsize.x * tsize.y * sizeof( gfx_terminal_uniform_block ), m_data->data );
+	m_data->buffer = m_context->create_buffer( nv::UNIFORM_BUFFER, nv::STREAM_DRAW, tsize.x * tsize.y * sizeof( gfx_terminal_uniform_block ), m_data->data );
 	m_context->bind( m_data->buffer, 7 );
 	m_context->get_device()->set_opt_uniform( m_dc.p, "term_size", vec2( tsize ) );
@@ -151,7 +149,10 @@
 void gfx_terminal::update()
 {
-	m_context->bind( m_data->buffer, 7 );
-	m_context->update( m_data->buffer, m_data->data, 0, m_data->size.x * m_data->size.y * sizeof( gfx_terminal_uniform_block ) );
-	m_update_needed = false;
+	if ( m_update_needed )
+	{
+		m_context->bind( m_data->buffer, 7 );
+		m_context->update( m_data->buffer, m_data->data, 0, m_data->size.x * m_data->size.y * sizeof( gfx_terminal_uniform_block ) );
+		m_update_needed = false;
+	}
 }
 
Index: trunk/src/gfx/mesh_creator.cc
===================================================================
--- trunk/src/gfx/mesh_creator.cc	(revision 514)
+++ trunk/src/gfx/mesh_creator.cc	(revision 520)
@@ -87,4 +87,28 @@
 }
 
+
+nv::aabb nv::mesh_data_creator::calculate_aabb()
+{
+	NV_ASSERT_ALWAYS( m_pos_channel, "No position channel found!" );
+	vec3 minv;
+	vec3 maxv;
+
+	if ( m_pos_channel->size() > 0 )
+	{
+		minv = *reinterpret_cast<const vec3*>( m_pos_channel->raw_data() + m_pos_offset );
+		maxv = minv;
+	}
+
+	for ( uint32 c = 0; c < m_pos_channel->size(); ++c )
+	{
+		vec3 v = *reinterpret_cast<const vec3*>( m_pos_channel->raw_data() + c*m_pos_channel->element_size() + m_pos_offset );
+		minv = nv::math::min( minv, v );
+		maxv = nv::math::max( maxv, v );
+	}
+	vec3 extents  = maxv - minv;
+	vec3 hextents = extents * 0.5f;
+	vec3 halfv    = minv + hextents;
+	return aabb( nv::transform( halfv ), hextents );
+}
 
 void nv::mesh_data_creator::transform( const vec3& pos, const mat3& r33, float scale /*= 1.0f */ )
Index: trunk/src/gfx/skeleton_instance.cc
===================================================================
--- trunk/src/gfx/skeleton_instance.cc	(revision 514)
+++ trunk/src/gfx/skeleton_instance.cc	(revision 520)
@@ -182,2 +182,19 @@
 }
 
+void nv::skeleton_transforms::delocalize_rec( const data_node_tree& node_data, uint32 id, const transform& parent, const array_view< bool >& mask )
+{
+	transform global_mat = parent;
+	bool b = mask[id];
+	if ( !b )
+		global_mat = m_transforms[id];
+	else
+	{
+		global_mat *= m_transforms[id];
+		m_transforms[id] = global_mat;
+	}
+	for ( auto child : node_data.children( id ) )
+	{
+		delocalize_rec( node_data, child, global_mat, mask );
+	}
+}
+
