1 | // Copyright (C) 2015-2015 ChaosForge Ltd
|
---|
2 | // http://chaosforge.org/
|
---|
3 | //
|
---|
4 | // This file is part of Nova libraries.
|
---|
5 | // For conditions of distribution and use, see copying.txt file in root folder.
|
---|
6 |
|
---|
7 | #include "nv/engine/mesh_manager.hh"
|
---|
8 | #include "nv/formats/nmd_loader.hh"
|
---|
9 | #include "nv/io/c_file_system.hh"
|
---|
10 |
|
---|
11 | using namespace nv;
|
---|
12 |
|
---|
13 | resource< gpu_mesh > gpu_mesh_manager::create_resource( resource< data_channel_set > mesh )
|
---|
14 | {
|
---|
15 | if ( auto lmesh = mesh.lock() )
|
---|
16 | {
|
---|
17 | gpu_mesh* gm = new gpu_mesh;
|
---|
18 | gm->va = m_context->create_vertex_array( &*lmesh, STATIC_DRAW );
|
---|
19 | gm->count = lmesh->get_channel_size( slot::INDEX );
|
---|
20 | gm->shader = lmesh->get_channel( slot::BONEINDEX ) != nullptr ? BONE : NORMAL;
|
---|
21 | return add( mesh.id(), gm );
|
---|
22 | }
|
---|
23 | return resource< gpu_mesh >();
|
---|
24 | }
|
---|
25 |
|
---|
26 | void gpu_mesh_manager::release( gpu_mesh* m )
|
---|
27 | {
|
---|
28 | m_context->release( m->va );
|
---|
29 | }
|
---|
30 |
|
---|
31 | 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 */ )
|
---|
32 | {
|
---|
33 | nv::resource< nv::mesh_data > mr = default;
|
---|
34 |
|
---|
35 | nv::string_view sub_mesh_name;
|
---|
36 | nv::string128 base_mesh_name( path );
|
---|
37 | nv::size_t sub_mesh_pos = path.find( ":" );
|
---|
38 | nv::size_t dot_pos = path.find( "." );
|
---|
39 | if ( sub_mesh_pos != nv::string_view::npos )
|
---|
40 | {
|
---|
41 | sub_mesh_name = path.substr( sub_mesh_pos + 1 );
|
---|
42 | base_mesh_name.assign( path.substr( 0, sub_mesh_pos ) );
|
---|
43 | NV_LOG_INFO( "Requested submesh - [", sub_mesh_name, "] in [", base_mesh_name, "]" );
|
---|
44 | }
|
---|
45 |
|
---|
46 | if ( dot_pos != nv::string_view::npos )
|
---|
47 | {
|
---|
48 | mr = get( base_mesh_name );
|
---|
49 | }
|
---|
50 | else
|
---|
51 | {
|
---|
52 | sub_mesh_name = base_mesh_name;
|
---|
53 | }
|
---|
54 |
|
---|
55 | if ( !mr )
|
---|
56 | {
|
---|
57 | NV_LOG_ERROR( "MESH FILE NOT FOUND - ", path );
|
---|
58 | NV_ASSERT( false, "MESH FILE NOT FOUND!" );
|
---|
59 | return nv::resource< nv::data_channel_set >();
|
---|
60 | }
|
---|
61 |
|
---|
62 | if ( auto mdata = mr.lock() )
|
---|
63 | {
|
---|
64 | sint32 index = -1;
|
---|
65 | if ( sub_mesh_name.empty() )
|
---|
66 | {
|
---|
67 | index = 0;
|
---|
68 | }
|
---|
69 | else if ( sub_mesh_name[0] >= '0' && sub_mesh_name[0] <= '9' )
|
---|
70 | {
|
---|
71 | index = nv::buffer_to_uint32( sub_mesh_name.data(), nullptr );
|
---|
72 | }
|
---|
73 | else
|
---|
74 | {
|
---|
75 | auto itr = mdata->names.find( sub_mesh_name );
|
---|
76 | if ( itr != mdata->names.end() )
|
---|
77 | index = itr->second;
|
---|
78 | }
|
---|
79 | if ( index >= 0 )
|
---|
80 | {
|
---|
81 | if ( info )
|
---|
82 | *info = mdata->infos[index];
|
---|
83 | return mdata->meshes[index];
|
---|
84 | }
|
---|
85 |
|
---|
86 | NV_LOG_ERROR( "Resource path fail! - ", path );
|
---|
87 | NV_ASSERT( false, "Resource path fail!" );
|
---|
88 | }
|
---|
89 | else
|
---|
90 | {
|
---|
91 | NV_LOG_ERROR( "Resource lock fail! - ", path );
|
---|
92 | NV_ASSERT( false, "Resource lock fail!" );
|
---|
93 | }
|
---|
94 | return nv::resource< nv::data_channel_set >();
|
---|
95 | }
|
---|
96 |
|
---|
97 | bool nv::mesh_data_manager::load_resource( const string_view& id )
|
---|
98 | {
|
---|
99 | nmd_loader* loader = nullptr;
|
---|
100 | c_file_system fs;
|
---|
101 | stream* mesh_file = open_stream( fs, id );
|
---|
102 | if ( !mesh_file ) return false;
|
---|
103 |
|
---|
104 | loader = new nmd_loader( m_strings );
|
---|
105 | loader->load( *mesh_file );
|
---|
106 | delete mesh_file;
|
---|
107 |
|
---|
108 | mesh_data* result = new mesh_data;
|
---|
109 | result->node_data = loader->release_data_node_list();
|
---|
110 | if ( result->node_data )
|
---|
111 | {
|
---|
112 | data_node_list* nd = result->node_data;
|
---|
113 | for ( uint32 i = 0; i < nd->size(); ++i )
|
---|
114 | result->node_names[(*nd)[i].name] = i;
|
---|
115 | }
|
---|
116 | for ( uint32 i = 0; i < loader->get_mesh_count(); ++i )
|
---|
117 | {
|
---|
118 | data_node_info info;
|
---|
119 | data_channel_set* data = loader->release_mesh_data( i, info );
|
---|
120 | result->infos.push_back( info );
|
---|
121 | result->names[ info.name ] = i;
|
---|
122 | auto mesh = m_mesh_manager->add( shash64( id.get_hash() + i ), data );
|
---|
123 | result->meshes.push_back( mesh );
|
---|
124 | }
|
---|
125 | delete loader;
|
---|
126 | if ( result )
|
---|
127 | add( id, result );
|
---|
128 | return result != nullptr;
|
---|
129 | }
|
---|