Index: /trunk/nv/formats/assimp_loader.hh
===================================================================
--- /trunk/nv/formats/assimp_loader.hh	(revision 276)
+++ /trunk/nv/formats/assimp_loader.hh	(revision 277)
@@ -15,4 +15,5 @@
 namespace nv 
 {
+
 	struct assimp_bone
 	{
@@ -60,4 +61,5 @@
 	public:
 		assimp_loader( const string& a_ext, const mat4& a_rotate_transform, float a_scale, uint32 a_assimp_flags = 0 );
+		explicit assimp_loader( const string& a_ext, uint32 a_assimp_flags = 0 );
 		virtual bool load( stream& source );
 		virtual mesh_data* release_mesh_data( size_t index = 0 );
Index: /trunk/nv/interface/device.hh
===================================================================
--- /trunk/nv/interface/device.hh	(revision 276)
+++ /trunk/nv/interface/device.hh	(revision 277)
@@ -62,4 +62,5 @@
 		vertex_array* create_vertex_array( const VTX* v, size_t count, buffer_hint hint )
 		{
+			// TODO: vb will not be owned or freed!
 			vertex_array*  va = create_vertex_array();
 			vertex_buffer* vb = create_vertex_buffer( hint, count * sizeof( VTX ), v );
Index: /trunk/nv/interface/program.hh
===================================================================
--- /trunk/nv/interface/program.hh	(revision 276)
+++ /trunk/nv/interface/program.hh	(revision 277)
@@ -162,5 +162,5 @@
 		void set_opt_uniform_array( const string& name, const T* value, uint32 count )
 		{
-			uniform_base* base = get_uniform( name );
+			uniform_base* base = try_get_uniform( name );
 			if (!base) return;
 			// restore typechecking, but remember to accept int for float!
Index: /trunk/src/formats/assimp_loader.cc
===================================================================
--- /trunk/src/formats/assimp_loader.cc	(revision 276)
+++ /trunk/src/formats/assimp_loader.cc	(revision 277)
@@ -13,4 +13,5 @@
 using namespace nv;
 
+const int MAX_BONES = 64;
 
 nv::assimp_loader::assimp_loader( const string& a_ext, const mat4& a_rotate_transform, float a_scale, uint32 a_assimp_flags /*= 0 */ ) : m_ext( a_ext ), m_rotate_transform( a_rotate_transform ), m_scale( a_scale ), m_assimp_flags( a_assimp_flags ), m_mesh_count(0), m_scene( nullptr )
@@ -35,5 +36,24 @@
 }
 
-
+nv::assimp_loader::assimp_loader( const string& a_ext, uint32 a_assimp_flags /*= 0 */ ) : m_ext( a_ext ), m_rotate_transform(), m_scale( 1.0f ), m_assimp_flags( a_assimp_flags ), m_mesh_count(0), m_scene( nullptr )
+{
+	if ( m_assimp_flags == 0 )
+	{
+		m_assimp_flags = ( 
+			aiProcess_CalcTangentSpace				|  
+			aiProcess_GenSmoothNormals				|  
+			aiProcess_JoinIdenticalVertices			|   
+			aiProcess_ImproveCacheLocality			|  
+			aiProcess_LimitBoneWeights				|  
+			aiProcess_RemoveRedundantMaterials      |  
+			aiProcess_SplitLargeMeshes				|  
+			aiProcess_Triangulate					|  
+			aiProcess_GenUVCoords                   |  
+			aiProcess_SortByPType                   |  
+			aiProcess_FindDegenerates               |  
+			aiProcess_FindInvalidData               |  
+			0 );
+	}
+}
 bool nv::assimp_loader::load( stream& source )
 {
@@ -68,7 +88,6 @@
 	mat3 scaled_rotatation = glm::mat3( glm::scale( m_scale, m_scale, m_scale ) * m_rotate_transform );
 	vec3 vertex_offset     = glm::vec3(); 
-	mat3 vertex_transform  = glm::mat3( glm::transpose( scaled_rotatation ) );
-	mat3 normal_transform  = glm::mat3( glm::transpose( glm::inverse( scaled_rotatation ) ) );
-	mat4 bone_transform    = glm::scale( 1.0f/m_scale, 1.0f/m_scale, 1.0f/m_scale ) * m_rotate_transform;
+	mat3 vertex_transform  = scaled_rotatation;
+	mat3 normal_transform  = glm::mat3( m_rotate_transform );
 
 	bool skinned = mesh->mNumBones > 0;
@@ -104,5 +123,4 @@
 		{
 			aiBone* bone  = mesh->mBones[m];
-			nv::mat4 offset = nv::assimp_mat4_cast( bone->mOffsetMatrix ) * bone_transform;
 			for (unsigned int w=0; w<bone->mNumWeights; w++)
 			{
@@ -151,5 +169,5 @@
 	if ( mesh->mNumBones == 0 ) return false;
 
-	mat4 bone_transform    = glm::scale( 1.0f/m_scale, 1.0f/m_scale, 1.0f/m_scale ) * m_rotate_transform;
+	mat4 bone_transform    = glm::inverse( glm::scale( m_scale, m_scale, m_scale ) * glm::mat4(m_rotate_transform) ); //glm::scale( 1.f/m_scale, 1.f/m_scale, 1.f/m_scale ) * m_rotate_transform;
 
 	for (unsigned int m=0; m<mesh->mNumBones; m++)
@@ -250,5 +268,5 @@
 	for ( unsigned int m = 0; m < model->meshes.size(); ++m )
 	{
-		nv::sint16 translate[64];
+		sint16 translate[MAX_BONES];
 		std::vector< assimp_bone > bones;
 		load_bones( m, bones );
@@ -256,10 +274,10 @@
 		{
 
-			nv::assimp_bone& bone = bones[b];
+			assimp_bone& bone = bones[b];
 			auto iname = names.find( bone.name );
 			if ( iname == names.end() )
 			{
-				NV_ASSERT( model->bones.size() < 64, "Too many bones to merge!" );
-				nv::sint16 index = (nv::sint16)model->bones.size();
+				NV_ASSERT( model->bones.size() < MAX_BONES, "Too many bones to merge!" );
+				sint16 index = (sint16)model->bones.size();
 				model->bones.push_back( bone );
 				names[ bone.name ] = index;
@@ -268,5 +286,5 @@
 			else
 			{
-				translate[b] = (nv::sint16)iname->second;
+				translate[b] = (sint16)iname->second;
 			}
 		}
@@ -274,11 +292,11 @@
 		{
 			mesh_data* mesh = model->meshes[m];
-			nv::mesh_raw_channel* channel = mesh->get_channel_data()[0];
-			nv::assimp_skinned_vtx* va = (nv::assimp_skinned_vtx*)channel->data;
+			mesh_raw_channel* channel = mesh->get_channel_data()[0];
+			assimp_skinned_vtx* va = (assimp_skinned_vtx*)channel->data;
 			for ( unsigned v = 0; v < channel->count; ++v )
 			{
-				nv::assimp_skinned_vtx& vertex = va[v];
-
-				for (nv::uint32 i = 0 ; i < 4; ++i)
+				assimp_skinned_vtx& vertex = va[v];
+
+				for (uint32 i = 0 ; i < 4; ++i)
 				{
 					if ( vertex.boneweight[i] > 0.0f ) 
