Index: trunk/src/formats/md5_loader.cc
===================================================================
--- trunk/src/formats/md5_loader.cc	(revision 440)
+++ 	(revision )
@@ -1,545 +1,0 @@
-// Copyright (C) 2012-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/formats/md5_loader.hh"
-
-#include "nv/core/logging.hh"
-#include "nv/stl/vector.hh"
-#include "nv/io/std_stream.hh"
-#include "nv/interface/data_channel_access.hh"
-
-#include <stdio.h>  // sscanf
-#include <stdlib.h> // atof
-
-#include <string> // TODO: remove
-
-using namespace nv;
-
-static void next_line( std::istream& stream )
-{
-	stream.ignore( 1024*1024, '\n' );
-}
-
-static inline void discard( std::istream& stream, const std::string& token )
-{
-	std::string discarded;
-	stream >> discarded;
-	assert( discarded == token );
-}
-
-static void remove_quotes( std::string& str )
-{
-	nv::size_t n;
-	while ( ( n = str.find('\"') ) != std::string::npos ) str.erase(n,1);
-}
-
-static void unit_quat_w( nv::quat& quat )
-{
-	float t = 1.0f - ( quat.x * quat.x ) - ( quat.y * quat.y ) - ( quat.z * quat.z );
-	quat.w = ( t < 0.0f ? 0.0f : -sqrtf(t) );
-}
-
-bool md5_loader::load( stream& source )
-{
-	reset();
-	std_stream sstream( &source );
-	std::string command;
-	size_t num_joints = 0;
-
-	// MESH data
-	dynamic_array< md5_weight > weights;
-	dynamic_array< md5_weight_info > weight_info;
-	size_t num_meshes = 0;
-
-	// MESH data
-	dynamic_array< md5_joint_info > joint_infos;
-	vector< transform >             base_frames;
-	size_t num_animated_components = 0;
-	size_t frame_rate = 0;
-	size_t num_frames = 0;
-
-	sstream >> command;
-	while ( !sstream.eof() )
-	{
-		if ( command == "MD5Version" )
-		{
-			sstream >> m_md5_version;
-			assert( m_md5_version == 10 );
-		}
-		else if ( command == "commandline" )
-		{
-			next_line( sstream ); 
-		}
-		else if ( command == "numJoints" )
-		{
-			sstream >> num_joints;
-			next_line( sstream ); 
-		}
-		else if ( command == "numMeshes" )
-		{
-			assert( m_type == UNKNOWN );
-			m_type = MESH;
-			sstream >> num_meshes;
-			m_meshes.resize( num_meshes );
-			num_meshes = 0;
-		}
-		else if ( command == "numFrames" )
-		{
-			assert( m_type == UNKNOWN || m_type == ANIMATION );
-			m_type = ANIMATION;
-			sstream >> num_frames;
-			next_line( sstream ); 
-		}
-		else if ( command == "frameRate" )
-		{
-			assert( m_type == UNKNOWN || m_type == ANIMATION );
-			m_type = ANIMATION;
-			sstream >> frame_rate;
-			next_line( sstream ); 
-		}
-		else if ( command == "numAnimatedComponents" )
-		{
-			assert( m_type == UNKNOWN || m_type == ANIMATION );
-			m_type = ANIMATION;
-			sstream >> num_animated_components;
-			next_line( sstream ); 
-		}
-		else if ( command == "joints" )
-		{
-			assert( m_type == MESH );
-			assert( m_nodes == nullptr );
-			m_nodes = new mesh_nodes_data( make_name( "md5_bones") );
-			discard( sstream, "{" );
-			for ( size_t i = 0; i < m_nodes->size(); ++i )
-			{
-				std::string name;
-				sint16 parent_id;
-				sstream >> name >> parent_id;
-				vec3 pos;
-				quat orient;
-				discard( sstream, "(" );
-				sstream >> pos.x >> pos.y >> pos.z;
-				discard( sstream, ")" );
-				discard( sstream, "(" );
-				sstream >> orient.x >> orient.y >> orient.z;
-				unit_quat_w( orient );
-				remove_quotes( name );
-				data_channel_set* set = data_channel_set_creator::create_set( 0 );
-				data_channel_set_creator access( set );
-				access.set_parent_id( parent_id );
-				access.set_transform( transform( pos, orient ).inverse().extract() );
-				access.set_name( make_name( name.c_str() ) );
-				next_line( sstream );
-				m_nodes->push_back( set );
-			}
-			discard( sstream, "}" );
-		}
-		else if ( command == "mesh" )
-		{
-			assert( m_type == MESH );
-			data_channel_set* mesh = data_channel_set_creator::create_set( 4 );
-			data_channel_set_creator maccess( mesh );
-
-			uint32 num_verts   = 0;
-			uint32 num_tris    = 0;
-			uint32 num_weights = 0;
-
-			discard( sstream, "{" );
-			sstream >> command;
-			while ( command != "}" ) 
-			{
-				if ( command == "shader" )
-				{
-					std::string shader;
-					sstream >> shader;
-					remove_quotes( shader );
-					maccess.set_name( make_name( shader.c_str() ) );
-					next_line( sstream );
-				}
-				else if ( command == "numverts")
-				{
-					sstream >> num_verts; 
-
-					md5_vtx_t* tdata = nullptr;
-					{
-						maccess.add_channel<md5_vtx_pnt>( num_verts );
-						tdata = maccess.add_channel<md5_vtx_t>( num_verts ).data();
-						maccess.add_channel<md5_vtx_pntiw>( num_verts );
-					}
-					weight_info.resize( num_verts );
-
-					next_line( sstream );
-					std::string line;
-					for ( uint32 i = 0; i < num_verts; ++i )
-					{
-						size_t weight_count;
-						size_t start_weight;
-						vec2 texcoord;
-
-						std::getline( sstream, line );
-						sscanf( line.c_str(), "%*s %*u ( %f %f ) %u %u", &(texcoord.x), &(texcoord.y), &(start_weight), &(weight_count) );
-						weight_info[i].start_weight = start_weight;
-						weight_info[i].weight_count = weight_count;
-						tdata[i].texcoord = texcoord;
-					}  
-				}
-				else if ( command == "numtris" )
-				{
-					sstream >> num_tris;
-
-					uint32* vtx_i = reinterpret_cast< uint32* >( maccess.add_channel< index_u32 >( num_tris * 3 ).raw_data() );
-					uint32 idx = 0;
-
-					next_line( sstream );
-					std::string line;
-					for ( uint32 i = 0; i < num_tris; ++i )
-					{
-						unsigned ti0;
-						unsigned ti1;
-						unsigned ti2;
-
-						std::getline( sstream, line );
-						sscanf( line.c_str(), "%*s %*u %u %u %u )", &(ti0), &(ti1), &(ti2));
-
-						vtx_i[idx++] = ti0;
-						vtx_i[idx++] = ti1;
-						vtx_i[idx++] = ti2;
-					}              
-
-				}
-				else if ( command == "numweights" )
-				{
-					sstream >> num_weights;
-					weights.resize( num_weights );
-					next_line( sstream );
-					std::string line;
-					for ( uint32 i = 0; i < num_weights; ++i )
-					{
-						md5_weight weight;
-
-						std::getline( sstream, line );
-						sscanf( line.c_str(), "%*s %*u %u %f ( %f %f %f )", &(weight.joint_id), &(weight.bias), &(weight.pos.x), &(weight.pos.y), &(weight.pos.z));
- 						weights[i] = weight;
-					}
-				}
-				else
-				{
-					next_line( sstream );
-				}
-
-				sstream >> command;
-			}
-
-			prepare_mesh( m_nodes, weight_info.size(), mesh, weights.data(), weight_info.data() );
-
-			m_meshes[ num_meshes ] = mesh;
-			num_meshes++;
-		} // mesh
-		else if ( command == "hierarchy" )
-		{
-			assert( m_type == ANIMATION );
-			assert( m_nodes == nullptr );
-			m_nodes = new mesh_nodes_data( make_name( "md5_animation" ), static_cast< nv::uint16 >( frame_rate ), static_cast< float >( num_frames ), true );
-			joint_infos.resize( num_joints );
-
-			discard( sstream, "{" );
-			for ( size_t i = 0; i < m_nodes->size(); ++i )
-			{
-				std::string    name;
-				sint16 parent_id;
-				sstream >> name >> parent_id >> joint_infos[i].flags >> joint_infos[i].start_index;
-				remove_quotes( name );
-				data_channel_set* set = data_channel_set_creator::create_set( 1 );
-				data_channel_set_creator access( set );
-				access.add_channel< md5_key_t >( num_frames );
-				access.set_name( make_name( name.c_str() ) );
-				access.set_parent_id( parent_id );
-				m_nodes->push_back( set );
-				next_line( sstream );
-			}
-			discard( sstream, "}" );
-		}
-		else if ( command == "bounds" )
-		{
-			assert( m_type == ANIMATION );
-			discard( sstream, "{" );
-			next_line( sstream ); 
-			for ( size_t i = 0; i < num_frames; ++i ) 
-			{
-				//  				vec3 min;
-				//  				vec3 max;
-				//  				discard( sstream, "(" );
-				//  				sstream >> min.x >> min.y >> min.z;
-				//  				discard( sstream, ")" );
-				//  				discard( sstream, "(" );
-				//  				sstream >> max.x >> max.y >> max.z;
-				// 				m_bounds.push_back( bound );
-				next_line( sstream ); 
-			}
-
-			discard( sstream, "}" );
-			next_line( sstream ); 
-		}
-		else if ( command == "baseframe" )
-		{
-			assert( m_type == ANIMATION );
-			discard( sstream, "{" );
-			next_line( sstream ); 
-
-			for ( size_t i = 0; i < m_nodes->size(); ++i )
-			{
-				transform base_frame;
-				vec3 pos;
-				quat orient;
-				discard( sstream, "(" );
-				sstream >> pos.x >> pos.y >> pos.z;
-				discard( sstream, ")" );
-				discard( sstream, "(" );
-				sstream >> orient.x >> orient.y >> orient.z;
-				next_line( sstream ); 
-
-				base_frames.emplace_back( pos, orient );
-			}
-			discard( sstream, "}" );
-			next_line( sstream ); 
-		}
-		else if ( command == "frame" )
-		{
-			vector<float> frame;
-			uint32 frame_id;
-			sstream >> frame_id;
-			discard( sstream, "{" );
-			next_line( sstream ); 
-
-			frame.reserve( num_animated_components );
-			char buf[50];
-			for ( size_t i = 0; i < num_animated_components; ++i )
-			{
-				sstream >> buf;
-				frame.push_back( static_cast< float >( atof(buf) ) );
-			}
-
-			build_frame_skeleton( m_nodes, frame_id, joint_infos, base_frames, frame );
-
-			discard( sstream, "}" );
-			next_line( sstream ); 
-		}
-
-		sstream >> command;
-	}
-
-	return true;
-}
-
-bool md5_loader::prepare_mesh( mesh_nodes_data* nodes, uint32 vtx_count, data_channel_set* mdata, md5_weight* weights, md5_weight_info* weight_info )
-{
-	assert( m_type == MESH );
-	data_channel_access< md5_vtx_pnt >   pnt  ( const_cast< raw_data_channel* >( mdata->get_channel< md5_vtx_pnt >() ) );
-	data_channel_access< md5_vtx_pntiw > pntiw( const_cast< raw_data_channel* >( mdata->get_channel< md5_vtx_pntiw >() ) );
-	md5_vtx_pntiw* vtx_data = pntiw.data();
-	md5_vtx_pnt* vtcs = pnt.data();
-
-	for ( uint32 i = 0; i < vtx_count; ++i )
-	{
-		size_t start_weight = weight_info[i].start_weight;
-		size_t weight_count = weight_info[i].weight_count;
-		md5_vtx_pntiw& vdata = vtx_data[i];
-		md5_vtx_pnt& vtc = vtcs[i];
-
-		vtc.position = vec3(0);
-		vtc.normal   = vec3(0);
-		vtc.tangent  = vec3(0);
-
-		stable_sort( weights + start_weight, weights + start_weight + weight_count, [] ( const md5_weight& a, const md5_weight& b ) -> bool { return a.bias > b.bias; } );
-		//std::sort( weights + start_weight, weights + start_weight + weight_count, [](const md5_weight& a, const md5_weight& b) -> bool { return a.bias > b.bias; } );
-
-		if ( weight_count > 4 )
-		{
-			float sum = 0.0f;
-			for ( size_t j = 0; j < 4; ++j )
-			{
-				sum += weights[start_weight + j].bias;
-			}
-			float ratio = 1.0f / sum;
-			for ( size_t j = 0; j < 4; ++j )
-			{
-				weights[start_weight + j].bias = ratio * weights[start_weight + j].bias;
-			}
-			weight_count = 4;
-		}
-
-		for ( int j = 0; j < 4; ++j )
-		{
-			if ( j < int(weight_count) )
-			{
-				vdata.boneindex[j]  = int( weights[int(start_weight) + j].joint_id );
-				vdata.boneweight[j] = weights[int(start_weight) + j].bias;
-			}
-			else
-			{
-				vdata.boneindex[j]  = 0;
-				vdata.boneweight[j] = 0.0f;
-			}
-		}
-
-		for ( size_t j = 0; j < 4; ++j )
-		{
-			if ( j < weight_count )
-			{
-				md5_weight& weight             = weights[start_weight + j];
-				const data_channel_set*  joint = (*nodes)[weight.joint_id];
-				const transform tr = transform( joint->get_transform() ).inverse();
-				vec3 rot_pos = tr.get_orientation() * weight.pos;
-
-				vtc.position += ( tr.get_position() + rot_pos ) * weight.bias;
-			}
-		}
-	}
-
-	const uint32*    idata = reinterpret_cast< uint32* >( const_cast< uint8* >( mdata->get_channel( slot::INDEX )->raw_data() ) );
-	const md5_vtx_t* tdata = mdata->get_channel_data<md5_vtx_t>();
-
-	// Prepare normals
-	uint32 tri_count = mdata->get_channel_size( slot::INDEX ) / 3;
-	for ( unsigned int i = 0; i < tri_count; ++i )
-	{
-		uint32 ti0 = idata[ i * 3 ];
-		uint32 ti1 = idata[ i * 3 + 1 ];
-		uint32 ti2 = idata[ i * 3 + 2 ];
- 
-		vec3 v1 = vtcs[ ti0 ].position;
-		vec3 v2 = vtcs[ ti1 ].position;
-		vec3 v3 = vtcs[ ti2 ].position;
-		vec3 xyz1 = v3 - v1;
-		vec3 xyz2 = v2 - v1;
-
-		vec3 normal = glm::cross( xyz1, xyz2 );
-
-		vtcs[ ti0 ].normal += normal;
-		vtcs[ ti1 ].normal += normal;
-		vtcs[ ti2 ].normal += normal;
-
-		const vec2& w1 = tdata[ ti0 ].texcoord;
-		const vec2& w2 = tdata[ ti1 ].texcoord;
-		const vec2& w3 = tdata[ ti2 ].texcoord;
-
-		vec2 st1 = w3 - w1;
-		vec2 st2 = w2 - w1;
-
-		float coef = 1.0f / (st1.x * st2.y - st2.x * st1.y);
-
-		vec3 tangent = (( xyz1 * st2.y ) - ( xyz2 * st1.y )) * coef;
-
-		vtcs[ ti0 ].tangent += tangent;
-		vtcs[ ti1 ].tangent += tangent;
-		vtcs[ ti2 ].tangent += tangent;
-	}
-
-	for ( size_t i = 0; i < vtx_count; ++i )
-	{
-		md5_vtx_pntiw& vdata = vtx_data[i];
-
-		vec3 normal  = glm::normalize( vtcs[i].normal );
-		vec3 tangent = glm::normalize( vtcs[i].tangent );
-		vtcs[i].normal   = normal;
-		vtcs[i].tangent  = tangent;
-
-		vdata.position = vtcs[i].position;
-		vdata.normal   = vec3(0);
- 		vdata.tangent  = vec3(0);
- 
- 		for ( int j = 0; j < 4; ++j )
- 		{
-			const data_channel_set*  joint = ( *nodes )[vdata.boneindex[j]];
-			const transform tr = transform( joint->get_transform() ).inverse();
- 			vdata.normal  += ( normal  * tr.get_orientation() ) * vdata.boneweight[j];
- 			vdata.tangent += ( tangent * tr.get_orientation() ) * vdata.boneweight[j];
- 		}
-	}
-
-	return true;
-}
-
-void md5_loader::build_frame_skeleton( mesh_nodes_data* nodes, uint32 index, const array_view<md5_joint_info>& joint_infos, const array_view<transform>& base_frames, const array_view<float>& frame_data )
-{
-	assert( m_type == ANIMATION );
-	for ( unsigned int i = 0; i < joint_infos.size(); ++i )
-	{
-		unsigned int j = 0;
-
-		const md5_joint_info& jinfo = joint_infos[i];
-		const data_channel_set* joint = (*nodes)[i];
-		int parent_id         = joint->get_parent_id();
-
-		vec3 pos    = base_frames[i].get_position();
-		quat orient = base_frames[i].get_orientation();
-		if ( jinfo.flags & 1 )  pos.x    = frame_data[ jinfo.start_index + j++ ];
-		if ( jinfo.flags & 2 )  pos.y    = frame_data[ jinfo.start_index + j++ ];
-		if ( jinfo.flags & 4 )  pos.z    = frame_data[ jinfo.start_index + j++ ];
-		if ( jinfo.flags & 8 )  orient.x = frame_data[ jinfo.start_index + j++ ];
-		if ( jinfo.flags & 16 ) orient.y = frame_data[ jinfo.start_index + j++ ];
-		if ( jinfo.flags & 32 )	orient.z = frame_data[ jinfo.start_index + j++ ];
-		unit_quat_w( orient );
-
-		if ( parent_id >= 0 ) // Has a parent joint
-		{
-			const data_channel_set* pjoint = ( *nodes )[i];
-			const transform* ptv = reinterpret_cast< const transform* >( pjoint->get_channel(0)->raw_data() );
-			transform ptr;
-			if ( pjoint->get_channel(0)->size() > index ) ptr = ptv[ index ];
-			vec3 rot_pos = ptr.get_orientation() * pos;
-
-			pos    = ptr.get_position() + rot_pos;
-			orient = ptr.get_orientation() * orient;
-
-			orient = glm::normalize( orient );
-		}
-
-		reinterpret_cast< transform* >( const_cast< uint8* >( joint->get_channel(0)->raw_data() ) )[index] = transform( pos, orient );
-	}
-}
-
-data_channel_set* nv::md5_loader::release_mesh_data( size_t index )
-{
-	data_channel_set* result = m_meshes[ index ];
-	m_meshes[ index ] = nullptr;
-	return result;
-}
-
-mesh_nodes_data* nv::md5_loader::release_mesh_nodes_data( size_t )
-{
-	mesh_nodes_data* nodes = m_nodes;
-	m_nodes = nullptr; 
-	return nodes;
-}
-
-mesh_data_pack* nv::md5_loader::release_mesh_data_pack()
-{
-	uint32 size = m_meshes.size();
-	data_channel_set* meshes = data_channel_set_creator::create_set_array( size, 4 );
-	for ( uint32 i = 0; i < size; ++i )
-	{
-		meshes[i] = move( *m_meshes[i] );
-		delete m_meshes[i];
-		m_meshes[i] = nullptr;
-	}
-	return new mesh_data_pack( size, meshes, release_mesh_nodes_data() );
-}
-
-
-nv::md5_loader::~md5_loader()
-{
-	reset();
-}
-
-void nv::md5_loader::reset()
-{
-	if ( m_nodes ) delete m_nodes;
-	for ( auto m : m_meshes ) { if (m) delete m; }
-	m_meshes.resize(0);
-	m_nodes = nullptr;
-}
-
Index: trunk/src/lua/lua_map_tile.cc
===================================================================
--- trunk/src/lua/lua_map_tile.cc	(revision 440)
+++ trunk/src/lua/lua_map_tile.cc	(revision 441)
@@ -17,7 +17,4 @@
 #include "nv/lua/lua_raw.hh"
 
-// TODO: REMOVE
-#include <string>
-
 static const char* NLUA_MAP_TILE_METATABLE = "map_tile";
 
@@ -58,11 +55,10 @@
 	nv::map_area* map_area = nv::lua::detail::to_map_area( L, 3 );
 	lua_settop( L, 2 );
-	nv::string_view lts = nv::trimmed( lua_tostring( L, 1 ) );
-	std::string code( lts.data(), lts.size() );
-	std::string chars( " \r\t" );
+	nv::string_buffer code( nv::trimmed( lua_tostring( L, 1 ) ) );
+	nv::string_view chars( " \r\t" );
 	code.erase( nv::remove_if( code.begin(), code.end(),
 		[&chars] ( const char& c )
 	{
-		return chars.find( c ) != std::string::npos;
+		return chars.find( c ) != nv::string_view::npos;
 	} ), code.end() );
 
Index: trunk/src/lua/lua_raw.cc
===================================================================
--- trunk/src/lua/lua_raw.cc	(revision 440)
+++ trunk/src/lua/lua_raw.cc	(revision 441)
@@ -7,35 +7,31 @@
 #include "nv/lua/lua_raw.hh"
 
-nv::string_view nlua_typecontent( lua_State* L, int idx )
+nv::string64 nlua_typecontent( lua_State* L, int idx )
 {
 	int type = lua_type( L, idx );
 	switch ( type )
 	{
-	case LUA_TNONE          : return "NONE"; 
-	case LUA_TNIL		    : return "NIL"; 
-	case LUA_TBOOLEAN		: return lua_toboolean( L, idx ) == 0 ? "false" : "true"; 
-	//case LUA_TLIGHTUSERDATA	: return std::to_string( nv::uint64( lua_touserdata( L, idx ) ) ); 
-	//case LUA_TNUMBER		: return std::to_string( lua_tonumber( L, idx ) ); 
-	// TODO: copy to buffer?
-	case LUA_TSTRING		: return nlua_tostringview( L, idx ); 
-	case LUA_TTABLE		    : return "TABLE"; 
-	case LUA_TFUNCTION		: return "FUNCTION"; 
-//	case LUA_TUSERDATA		: return std::to_string( nv::uint64( lua_touserdata( L, idx ) ) ); 
-	case LUA_TTHREAD		: return "THREAD"; 
+	case LUA_TNONE          : return nv::string64( "NONE" );
+	case LUA_TNIL		    : return nv::string64( "NIL" );
+	case LUA_TBOOLEAN		: return nv::string64( lua_toboolean( L, idx ) == 0 ? "false" : "true" );
+	case LUA_TSTRING		: return nv::string64( nlua_tostringview( L, idx ) );
+	case LUA_TTABLE		    : return nv::string64( "TABLE" );
+	case LUA_TFUNCTION		: return nv::string64( "FUNCTION" );
+	case LUA_TTHREAD		: return nv::string64( "THREAD" );
 	default : break; 
 	}
-	static char buffer_data[64];
-	nv::array_ref< char > buffer( buffer_data, 64 );
 	if ( type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA )
 	{
+		nv::string64 buffer;
 		size_t l = nv::uint64_to_buffer( buffer, nv::uint64( lua_touserdata( L, idx ) ) );
-		return nv::string_view( buffer.data(), l );
+		return buffer;
 	}
 	else if ( type == LUA_TNUMBER )
 	{
+		nv::string64 buffer;
 		size_t l = nv::f64_to_buffer( buffer, lua_tonumber( L, idx ) );
-		return nv::string_view( buffer.data(), l );
-	}
-	return "UNKNOWN!";
+		return buffer;
+	}
+	return nv::string64( "UNKNOWN!" );
 }
 
