// Copyright (C) 2015-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/engine/mesh_manager.hh" #include "nv/formats/nmd_loader.hh" #include "nv/io/c_file_system.hh" using namespace nv; resource< gpu_mesh > gpu_mesh_manager::create_resource( resource< data_channel_set > mesh ) { if ( auto lmesh = mesh.lock() ) { gpu_mesh* gm = new gpu_mesh; gm->va = m_context->create_vertex_array( &*lmesh, STATIC_DRAW ); gm->count = lmesh->get_channel_size( slot::INDEX ); gm->shader = lmesh->get_channel( slot::BONEINDEX ) != nullptr ? BONE : DIRECT; return add( mesh.id(), gm ); } return resource< gpu_mesh >(); } void gpu_mesh_manager::release( gpu_mesh* m ) { m_context->release( m->va ); } nv::resource< nv::data_channel_set > nv::mesh_data_manager::get_path( const string_view& path, resource< mesh_data > default /*= resource< mesh_data >()*/, data_node_info* info /*= nullptr */ ) { nv::resource< nv::mesh_data > mr = default; nv::string_view sub_mesh_name; nv::string128 base_mesh_name( path ); nv::uint32 sub_mesh_pos = path.find( ":" ); nv::uint32 dot_pos = path.find( "." ); if ( sub_mesh_pos != nv::string_view::npos ) { sub_mesh_name = path.substr( sub_mesh_pos + 1 ); base_mesh_name.assign( path.substr( 0, sub_mesh_pos ) ); NV_LOG_INFO( "Requested submesh - [", sub_mesh_name, "] in [", base_mesh_name, "]" ); } if ( dot_pos != nv::string_view::npos ) { mr = get( base_mesh_name ); } else { sub_mesh_name = base_mesh_name; } if ( !mr ) { NV_LOG_ERROR( "MESH FILE NOT FOUND - ", path ); NV_ASSERT( false, "MESH FILE NOT FOUND!" ); return nv::resource< nv::data_channel_set >(); } if ( auto mdata = mr.lock() ) { sint32 index = -1; if ( sub_mesh_name.empty() ) { index = 0; } else if ( sub_mesh_name[0] >= '0' && sub_mesh_name[0] <= '9' ) { index = nv::buffer_to_uint32( sub_mesh_name.data(), nullptr ); } else { auto itr = mdata->names.find( sub_mesh_name ); if ( itr != mdata->names.end() ) index = itr->second; } if ( index >= 0 ) { if ( info ) *info = mdata->infos[index]; return mdata->meshes[index]; } NV_LOG_ERROR( "Resource path fail! - ", path ); //NV_ASSERT( false, "Resource path fail!" ); } else { NV_LOG_ERROR( "Resource lock fail! - ", path ); //NV_ASSERT( false, "Resource lock fail!" ); } return nv::resource< nv::data_channel_set >(); } bool nv::mesh_data_manager::load_resource( const string_view& id ) { nmd_loader* loader = nullptr; c_file_system fs; stream* mesh_file = open_stream( fs, id ); if ( !mesh_file ) return false; loader = new nmd_loader( m_strings ); loader->load( *mesh_file ); delete mesh_file; mesh_data* result = new mesh_data; result->node_data = loader->release_data_node_list(); if ( result->node_data ) { data_node_list* nd = result->node_data; for ( uint32 i = 0; i < nd->size(); ++i ) result->node_names[(*nd)[i].name] = i; } resource< mesh_data > rmesh = add( id, result ); for ( uint32 i = 0; i < loader->get_mesh_count(); ++i ) { data_node_info info; data_channel_set* data = loader->release_mesh_data( i, info ); result->infos.push_back( info ); result->names[ info.name ] = i; auto mesh = m_mesh_manager->add( shash64( id.get_hash() + i ), data ); result->meshes.push_back( mesh ); m_source_map[mesh.id()] = mesh_source{ rmesh, i }; } result->path.assign( id ); delete loader; return result != nullptr; }