11use std:: sync:: Arc ;
22
33use ahash:: { HashMap , HashMapExt } ;
4- use anyhow:: Context as _;
54use gltf:: texture:: WrappingMode ;
65use itertools:: Itertools ;
76use smallvec:: SmallVec ;
87
98use crate :: {
10- mesh:: { Material , Mesh } ,
9+ mesh:: { Material , Mesh , MeshError } ,
1110 renderer:: MeshInstance ,
1211 resource_managers:: {
13- GpuMeshHandle , GpuTexture2D , ResourceLifeTime , Texture2DCreationDesc , TextureManager2D ,
12+ GpuMeshHandle , GpuTexture2D , ResourceLifeTime , ResourceManagerError , Texture2DCreationDesc ,
13+ TextureManager2D ,
1414 } ,
1515 RenderContext , Rgba32Unmul ,
1616} ;
1717
18+ #[ derive( thiserror:: Error , Debug ) ]
19+ pub enum GltfImportError {
20+ #[ error( transparent) ]
21+ GltfLoading ( #[ from] gltf:: Error ) ,
22+
23+ #[ error( transparent) ]
24+ ResourceManager ( #[ from] ResourceManagerError ) ,
25+
26+ #[ error( transparent) ]
27+ MeshError ( #[ from] MeshError ) ,
28+
29+ #[ error( "Unsupported texture format {0:?}." ) ]
30+ UnsupportedTextureFormat ( gltf:: image:: Format ) ,
31+
32+ #[ error( "Mesh {mesh_name:?} has multiple sets of texture coordinates. Only a single one is supported." ) ]
33+ MultipleTextureCoordinateSets { mesh_name : String } ,
34+
35+ #[ error( "Mesh {mesh_name:?} has no triangles." ) ]
36+ NoIndices { mesh_name : String } ,
37+
38+ #[ error( "Mesh {mesh_name:?} has no vertex positions." ) ]
39+ NoPositions { mesh_name : String } ,
40+
41+ #[ error( "Mesh {mesh_name:?} has no triangle primitives." ) ]
42+ NoTrianglePrimitives { mesh_name : String } ,
43+ }
44+
1845/// Loads both gltf and glb into the mesh & texture manager.
1946pub fn load_gltf_from_buffer (
2047 mesh_name : & str ,
2148 buffer : & [ u8 ] ,
2249 lifetime : ResourceLifeTime ,
2350 ctx : & RenderContext ,
24- ) -> anyhow :: Result < Vec < MeshInstance > > {
51+ ) -> Result < Vec < MeshInstance > , GltfImportError > {
2552 re_tracing:: profile_function!( ) ;
2653
2754 let ( doc, buffers, images) = {
@@ -44,7 +71,7 @@ pub fn load_gltf_from_buffer(
4471 crate :: pad_rgb_to_rgba ( & image. pixels , 255 ) ,
4572 )
4673 } else {
47- anyhow :: bail! ( "Unsupported texture format {:?}" , image. format) ;
74+ return Err ( GltfImportError :: UnsupportedTextureFormat ( image. format ) ) ;
4875 }
4976 } ;
5077
@@ -93,8 +120,7 @@ pub fn load_gltf_from_buffer(
93120 for ref mesh in doc. meshes ( ) {
94121 re_tracing:: profile_scope!( "mesh" ) ;
95122
96- let re_mesh = import_mesh ( mesh, & buffers, & images_as_textures, & ctx. texture_manager_2d )
97- . with_context ( || format ! ( "mesh {} (name {:?})" , mesh. index( ) , mesh. name( ) ) ) ?;
123+ let re_mesh = import_mesh ( mesh, & buffers, & images_as_textures, & ctx. texture_manager_2d ) ?;
98124 meshes. insert (
99125 mesh. index ( ) ,
100126 (
@@ -140,9 +166,11 @@ fn import_mesh(
140166 buffers : & [ gltf:: buffer:: Data ] ,
141167 gpu_image_handles : & [ GpuTexture2D ] ,
142168 texture_manager : & TextureManager2D , //imported_materials: HashMap<usize, Material>,
143- ) -> anyhow :: Result < Mesh > {
169+ ) -> Result < Mesh , GltfImportError > {
144170 re_tracing:: profile_function!( ) ;
145171
172+ let mesh_name = mesh. name ( ) . map_or ( "<unknown" , |f| f) . to_owned ( ) ;
173+
146174 let mut triangle_indices = Vec :: new ( ) ;
147175 let mut vertex_positions = Vec :: new ( ) ;
148176 let mut vertex_colors = Vec :: new ( ) ;
@@ -171,13 +199,13 @@ fn import_mesh(
171199 . map ( glam:: UVec3 :: from) ,
172200 ) ;
173201 } else {
174- anyhow :: bail! ( "Gltf primitives must have indices" ) ;
202+ return Err ( GltfImportError :: NoIndices { mesh_name } ) ;
175203 }
176204
177205 if let Some ( primitive_positions) = reader. read_positions ( ) {
178206 vertex_positions. extend ( primitive_positions. map ( glam:: Vec3 :: from) ) ;
179207 } else {
180- anyhow :: bail! ( "Gltf primitives must have positions" ) ;
208+ return Err ( GltfImportError :: NoPositions { mesh_name } ) ;
181209 }
182210
183211 if let Some ( colors) = reader. read_colors ( set) {
@@ -206,10 +234,9 @@ fn import_mesh(
206234 let pbr_material = primitive_material. pbr_metallic_roughness ( ) ;
207235
208236 let albedo = if let Some ( texture) = pbr_material. base_color_texture ( ) {
209- anyhow:: ensure!(
210- texture. tex_coord( ) == 0 ,
211- "Only a single set of texture coordinates is supported"
212- ) ;
237+ if texture. tex_coord ( ) != 0 {
238+ return Err ( GltfImportError :: MultipleTextureCoordinateSets { mesh_name } ) ;
239+ }
213240 let texture = & texture. texture ( ) ;
214241
215242 let sampler = & texture. sampler ( ) ;
@@ -259,7 +286,7 @@ fn import_mesh(
259286 } ) ;
260287 }
261288 if vertex_positions. is_empty ( ) || triangle_indices. is_empty ( ) {
262- anyhow :: bail! ( "empty mesh" ) ;
289+ return Err ( GltfImportError :: NoTrianglePrimitives { mesh_name } ) ;
263290 }
264291
265292 let mesh = Mesh {
0 commit comments