From 6232e60217a3c85bcbeac0c0a11afd9608f280e8 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 14 Oct 2024 11:43:05 +0200 Subject: [PATCH 1/7] rename Mesh to CpuMesh for improved clarity, remove unused method --- crates/viewer/re_renderer/src/importer/gltf.rs | 8 ++++---- crates/viewer/re_renderer/src/importer/mod.rs | 13 +------------ crates/viewer/re_renderer/src/importer/obj.rs | 4 ++-- crates/viewer/re_renderer/src/importer/stl.rs | 2 +- crates/viewer/re_renderer/src/mesh.rs | 6 +++--- .../re_renderer/src/renderer/mesh_renderer.rs | 6 +++--- .../viewer/re_space_view_spatial/src/mesh_loader.rs | 2 +- .../viewer/re_space_view_spatial/src/proc_mesh.rs | 6 +++--- 8 files changed, 18 insertions(+), 29 deletions(-) diff --git a/crates/viewer/re_renderer/src/importer/gltf.rs b/crates/viewer/re_renderer/src/importer/gltf.rs index c4bcd41b4bc2..1dd3ed036882 100644 --- a/crates/viewer/re_renderer/src/importer/gltf.rs +++ b/crates/viewer/re_renderer/src/importer/gltf.rs @@ -6,7 +6,7 @@ use itertools::Itertools; use smallvec::SmallVec; use crate::{ - mesh::{GpuMesh, Material, Mesh, MeshError}, + mesh::{GpuMesh, Material, CpuMesh, MeshError}, renderer::MeshInstance, resource_managers::{GpuTexture2D, ImageDataDesc, TextureManager2D}, RenderContext, Rgba32Unmul, @@ -154,7 +154,7 @@ fn import_mesh( buffers: &[gltf::buffer::Data], gpu_image_handles: &[GpuTexture2D], texture_manager: &TextureManager2D, //imported_materials: HashMap, -) -> Result { +) -> Result { re_tracing::profile_function!(); let mesh_name = mesh.name().map_or(", node: &gltf::Node<'_>, transform: &glam::Affine3A, - meshes: &HashMap, Arc)>, + meshes: &HashMap, Arc)>, ) { let (scale, rotation, translation) = match node.transform() { gltf::scene::Transform::Matrix { matrix } => { diff --git a/crates/viewer/re_renderer/src/importer/mod.rs b/crates/viewer/re_renderer/src/importer/mod.rs index 7b5c42c313f6..daf29eda4060 100644 --- a/crates/viewer/re_renderer/src/importer/mod.rs +++ b/crates/viewer/re_renderer/src/importer/mod.rs @@ -7,20 +7,9 @@ pub mod gltf; #[cfg(feature = "import-stl")] pub mod stl; -use re_math::Vec3Ext as _; - use crate::renderer::MeshInstance; -pub fn to_uniform_scale(scale: glam::Vec3) -> f32 { - if scale.has_equal_components(0.001) { - scale.x - } else { - let uniform_scale = (scale.x * scale.y * scale.z).cbrt(); - re_log::warn!("mesh has non-uniform scale ({:?}). This is currently not supported. Using geometric mean {}", scale,uniform_scale); - uniform_scale - } -} - +// TODO: make this part of the cpu model only. pub fn calculate_bounding_box(instances: &[MeshInstance]) -> re_math::BoundingBox { re_math::BoundingBox::from_points( instances diff --git a/crates/viewer/re_renderer/src/importer/obj.rs b/crates/viewer/re_renderer/src/importer/obj.rs index 88414dd16782..c3f7438b2390 100644 --- a/crates/viewer/re_renderer/src/importer/obj.rs +++ b/crates/viewer/re_renderer/src/importer/obj.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use smallvec::smallvec; use crate::{ - mesh::{GpuMesh, Material, Mesh, MeshError}, + mesh::{GpuMesh, Material, CpuMesh, MeshError}, renderer::MeshInstance, RenderContext, Rgba32Unmul, }; @@ -84,7 +84,7 @@ pub fn load_obj_from_buffer( let texture = ctx.texture_manager_2d.white_texture_unorm_handle(); - let mesh = Mesh { + let mesh = CpuMesh { label: model.name.into(), triangle_indices, vertex_positions, diff --git a/crates/viewer/re_renderer/src/importer/stl.rs b/crates/viewer/re_renderer/src/importer/stl.rs index a78994aef386..8a171b706e37 100644 --- a/crates/viewer/re_renderer/src/importer/stl.rs +++ b/crates/viewer/re_renderer/src/importer/stl.rs @@ -43,7 +43,7 @@ pub fn load_stl_from_buffer( albedo_factor: crate::Rgba::WHITE, }; - let mesh = mesh::Mesh { + let mesh = mesh::CpuMesh { label: name.into(), triangle_indices: (0..num_vertices as u32) .tuples::<(_, _, _)>() diff --git a/crates/viewer/re_renderer/src/mesh.rs b/crates/viewer/re_renderer/src/mesh.rs index e6e2589a4940..0c88c8c4774c 100644 --- a/crates/viewer/re_renderer/src/mesh.rs +++ b/crates/viewer/re_renderer/src/mesh.rs @@ -45,7 +45,7 @@ pub mod mesh_vertices { } #[derive(Clone)] -pub struct Mesh { +pub struct CpuMesh { pub label: DebugLabel, /// Non-empty array of vertex triangle indices. @@ -70,7 +70,7 @@ pub struct Mesh { pub materials: SmallVec<[Material; 1]>, } -impl Mesh { +impl CpuMesh { pub fn sanity_check(&self) -> Result<(), MeshError> { re_tracing::profile_function!(); @@ -210,7 +210,7 @@ pub(crate) mod gpu_data { impl GpuMesh { // TODO(andreas): Take read-only context here and make uploads happen on staging belt. - pub fn new(ctx: &RenderContext, data: &Mesh) -> Result { + pub fn new(ctx: &RenderContext, data: &CpuMesh) -> Result { re_tracing::profile_function!(); data.sanity_check()?; diff --git a/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs b/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs index 9b8be32f863a..6dfd74e21ae1 100644 --- a/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs +++ b/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs @@ -11,7 +11,7 @@ use smallvec::smallvec; use crate::{ draw_phases::{DrawPhase, OutlineMaskProcessor}, include_shader_module, - mesh::{gpu_data::MaterialUniformBuffer, mesh_vertices, GpuMesh, Mesh}, + mesh::{gpu_data::MaterialUniformBuffer, mesh_vertices, CpuMesh, GpuMesh}, view_builder::ViewBuilder, wgpu_resources::{ BindGroupLayoutDesc, BufferDesc, GpuBindGroupLayoutHandle, GpuBuffer, @@ -115,7 +115,7 @@ pub struct MeshInstance { pub gpu_mesh: Arc, /// Optional cpu representation of the mesh, not needed for rendering. - pub mesh: Option>, + pub mesh: Option>, /// Where this instance is placed in world space and how its oriented & scaled. pub world_from_mesh: glam::Affine3A, @@ -138,7 +138,7 @@ impl MeshInstance { } /// Creates a new instance of a mesh with gpu and optional cpu mesh. - pub fn new_with_cpu_mesh(gpu_mesh: Arc, cpu_mesh: Option>) -> Self { + pub fn new_with_cpu_mesh(gpu_mesh: Arc, cpu_mesh: Option>) -> Self { Self { gpu_mesh, mesh: cpu_mesh, diff --git a/crates/viewer/re_space_view_spatial/src/mesh_loader.rs b/crates/viewer/re_space_view_spatial/src/mesh_loader.rs index 1482486d258b..33833517e0aa 100644 --- a/crates/viewer/re_space_view_spatial/src/mesh_loader.rs +++ b/crates/viewer/re_space_view_spatial/src/mesh_loader.rs @@ -157,7 +157,7 @@ impl LoadedMesh { .clone() }); - let mesh = re_renderer::mesh::Mesh { + let mesh = re_renderer::mesh::CpuMesh { label: name.clone().into(), triangle_indices, vertex_positions: vertex_positions.into(), diff --git a/crates/viewer/re_space_view_spatial/src/proc_mesh.rs b/crates/viewer/re_space_view_spatial/src/proc_mesh.rs index f90ada8f6c1f..ba4ca7baa5ae 100644 --- a/crates/viewer/re_space_view_spatial/src/proc_mesh.rs +++ b/crates/viewer/re_space_view_spatial/src/proc_mesh.rs @@ -265,7 +265,7 @@ impl Cache for SolidCache { fn generate_solid(key: &ProcMeshKey, render_ctx: &RenderContext) -> Result { re_tracing::profile_function!(); - let mesh: mesh::Mesh = match *key { + let mesh: mesh::CpuMesh = match *key { ProcMeshKey::Cube => { let mut mg = re_math::MeshGen::new(); mg.push_cube(Vec3::splat(0.5), re_math::IsoTransform::IDENTITY); @@ -280,7 +280,7 @@ fn generate_solid(key: &ProcMeshKey, render_ctx: &RenderContext) -> Result Result Date: Fri, 18 Oct 2024 09:46:00 +0200 Subject: [PATCH 2/7] build out model datastructure and use it in all mesh importers --- .../re_renderer/src/importer/cpu_model.rs | 55 +++++++ .../viewer/re_renderer/src/importer/gltf.rs | 42 ++--- crates/viewer/re_renderer/src/importer/mod.rs | 4 + crates/viewer/re_renderer/src/importer/obj.rs | 151 +++++++++--------- crates/viewer/re_renderer/src/importer/stl.rs | 14 +- crates/viewer/re_renderer/src/lib.rs | 1 + 6 files changed, 157 insertions(+), 110 deletions(-) create mode 100644 crates/viewer/re_renderer/src/importer/cpu_model.rs diff --git a/crates/viewer/re_renderer/src/importer/cpu_model.rs b/crates/viewer/re_renderer/src/importer/cpu_model.rs new file mode 100644 index 000000000000..fca16822f815 --- /dev/null +++ b/crates/viewer/re_renderer/src/importer/cpu_model.rs @@ -0,0 +1,55 @@ +use slotmap::SlotMap; + +use crate::{ + mesh::{CpuMesh, MeshError}, + renderer::MeshInstance, +}; + +slotmap::new_key_type! { + /// Key for identifying a cpu mesh in a model. + pub struct CpuModelMeshKey; +} + +/// Like [`MeshInstance`], but for CPU sided usage in a [`CpuModel`] only. +pub struct CpuMeshInstance { + pub mesh: CpuModelMeshKey, + pub world_from_mesh: glam::Affine3A, + // TODO(andreas): Expose other properties we have on [`MeshInstance`]. +} + +/// A model as stored on the CPU. +/// +/// This is the output of a model loader and is ready to be converted into +/// a series of [`MeshInstance`]s that can be rendered. +/// +/// This is meant as a useful intermediate structure for doing post-processing steps on the model prior to gpu upload. +#[derive(Default)] +pub struct CpuModel { + pub meshes: SlotMap, + pub instances: Vec, +} + +impl CpuModel { + /// Creates a new [`CpuModel`] from a single [`CpuMesh`], creating a single instance with identity transform. + pub fn from_single_mesh(mesh: CpuMesh) -> Self { + let mut model = Self::default(); + model.add_single_instance_mesh(mesh); + model + } + + /// Adds a new [`CpuMesh`] to the model, creating a single instance with identity transform. + pub fn add_single_instance_mesh(&mut self, mesh: CpuMesh) { + let mesh_key = self.meshes.insert(mesh); + self.instances.push(CpuMeshInstance { + mesh: mesh_key, + world_from_mesh: glam::Affine3A::IDENTITY, + }); + } + + /// Converts the entire model into a serious of mesh instances that can be rendered. + // TODO(andreas): Should offer the option to discard or not discard the original mesh information + // since this can be a significant memory overhead. + pub fn to_gpu() -> Result, MeshError> { + todo!() + } +} diff --git a/crates/viewer/re_renderer/src/importer/gltf.rs b/crates/viewer/re_renderer/src/importer/gltf.rs index 1dd3ed036882..741efd200456 100644 --- a/crates/viewer/re_renderer/src/importer/gltf.rs +++ b/crates/viewer/re_renderer/src/importer/gltf.rs @@ -1,15 +1,12 @@ -use std::sync::Arc; - use ahash::{HashMap, HashMapExt}; use gltf::texture::WrappingMode; use itertools::Itertools; use smallvec::SmallVec; use crate::{ - mesh::{GpuMesh, Material, CpuMesh, MeshError}, - renderer::MeshInstance, + mesh::{CpuMesh, Material, MeshError}, resource_managers::{GpuTexture2D, ImageDataDesc, TextureManager2D}, - RenderContext, Rgba32Unmul, + CpuMeshInstance, CpuModel, CpuModelMeshKey, RenderContext, Rgba32Unmul, }; #[derive(thiserror::Error, Debug)] @@ -41,7 +38,7 @@ pub fn load_gltf_from_buffer( mesh_name: &str, buffer: &[u8], ctx: &RenderContext, -) -> Result, GltfImportError> { +) -> Result { re_tracing::profile_function!(); let (doc, buffers, images) = { @@ -105,25 +102,28 @@ pub fn load_gltf_from_buffer( }); } - let mut meshes = HashMap::with_capacity(doc.meshes().len()); + let mut re_model = CpuModel::default(); + let mut mesh_keys = HashMap::with_capacity(doc.meshes().len()); for ref mesh in doc.meshes() { re_tracing::profile_scope!("mesh"); let re_mesh = import_mesh(mesh, &buffers, &images_as_textures, &ctx.texture_manager_2d)?; - meshes.insert( - mesh.index(), - (Arc::new(GpuMesh::new(ctx, &re_mesh)?), Arc::new(re_mesh)), - ); + let re_mesh_key = re_model.meshes.insert(re_mesh); + mesh_keys.insert(mesh.index(), re_mesh_key); } - let mut instances = Vec::new(); for scene in doc.scenes() { for node in scene.nodes() { - gather_instances_recursive(&mut instances, &node, &glam::Affine3A::IDENTITY, &meshes); + gather_instances_recursive( + &mut re_model.instances, + &node, + &glam::Affine3A::IDENTITY, + &mesh_keys, + ); } } - Ok(instances) + Ok(re_model) } fn map_format(format: gltf::image::Format) -> Option { @@ -293,10 +293,10 @@ fn import_mesh( } fn gather_instances_recursive( - instances: &mut Vec, + instances: &mut Vec, node: &gltf::Node<'_>, transform: &glam::Affine3A, - meshes: &HashMap, Arc)>, + meshes: &HashMap, ) { let (scale, rotation, translation) = match node.transform() { gltf::scene::Transform::Matrix { matrix } => { @@ -324,11 +324,11 @@ fn gather_instances_recursive( } if let Some(mesh) = node.mesh() { - if let Some((gpu_mesh, mesh)) = meshes.get(&mesh.index()) { - let mut gpu_mesh = - MeshInstance::new_with_cpu_mesh(gpu_mesh.clone(), Some(mesh.clone())); - gpu_mesh.world_from_mesh = transform; - instances.push(gpu_mesh); + if let Some(mesh_key) = meshes.get(&mesh.index()) { + instances.push(CpuMeshInstance { + mesh: *mesh_key, + world_from_mesh: transform, + }); } } } diff --git a/crates/viewer/re_renderer/src/importer/mod.rs b/crates/viewer/re_renderer/src/importer/mod.rs index daf29eda4060..5e754cee315a 100644 --- a/crates/viewer/re_renderer/src/importer/mod.rs +++ b/crates/viewer/re_renderer/src/importer/mod.rs @@ -1,3 +1,5 @@ +mod cpu_model; + #[cfg(feature = "import-obj")] pub mod obj; @@ -7,6 +9,8 @@ pub mod gltf; #[cfg(feature = "import-stl")] pub mod stl; +pub use cpu_model::{CpuMeshInstance, CpuModel, CpuModelMeshKey}; + use crate::renderer::MeshInstance; // TODO: make this part of the cpu model only. diff --git a/crates/viewer/re_renderer/src/importer/obj.rs b/crates/viewer/re_renderer/src/importer/obj.rs index c3f7438b2390..c4b3cba39543 100644 --- a/crates/viewer/re_renderer/src/importer/obj.rs +++ b/crates/viewer/re_renderer/src/importer/obj.rs @@ -1,11 +1,8 @@ -use std::sync::Arc; - use smallvec::smallvec; use crate::{ - mesh::{GpuMesh, Material, CpuMesh, MeshError}, - renderer::MeshInstance, - RenderContext, Rgba32Unmul, + mesh::{CpuMesh, Material, MeshError}, + CpuModel, RenderContext, Rgba32Unmul, }; #[derive(thiserror::Error, Debug)] @@ -22,7 +19,7 @@ pub enum ObjImportError { pub fn load_obj_from_buffer( buffer: &[u8], ctx: &RenderContext, -) -> Result, ObjImportError> { +) -> Result { re_tracing::profile_function!(); let (models, _materials) = tobj::load_obj_buf( @@ -36,77 +33,73 @@ pub fn load_obj_from_buffer( )?; // TODO(andreas) Merge all obj meshes into a single re_renderer mesh with multiple materials. - models - .into_iter() - .map(|model| { - // This could be optimized by using bytemuck. - - let mesh = model.mesh; - let vertex_positions: Vec = mesh - .positions - .chunks_exact(3) - .map(|p| glam::vec3(p[0], p[1], p[2])) - .collect(); - - let triangle_indices = mesh - .indices - .chunks_exact(3) - .map(|p| glam::uvec3(p[0], p[1], p[2])) - .collect(); - - let mut vertex_colors: Vec = mesh - .vertex_color - .chunks_exact(3) - .map(|c| { - Rgba32Unmul::from_rgb( - // It is not specified if the color is in linear or gamma space, but gamma seems a safe bet. - (c[0] * 255.0).round() as u8, - (c[1] * 255.0).round() as u8, - (c[2] * 255.0).round() as u8, - ) - }) - .collect(); - vertex_colors.resize(vertex_positions.len(), Rgba32Unmul::WHITE); - - let mut vertex_normals: Vec = mesh - .normals - .chunks_exact(3) - .map(|n| glam::vec3(n[0], n[1], n[2])) - .collect(); - vertex_normals.resize(vertex_positions.len(), glam::Vec3::ZERO); - - let mut vertex_texcoords: Vec = mesh - .texcoords - .chunks_exact(2) - .map(|t| glam::vec2(t[0], t[1])) - .collect(); - vertex_texcoords.resize(vertex_positions.len(), glam::Vec2::ZERO); - - let texture = ctx.texture_manager_2d.white_texture_unorm_handle(); - - let mesh = CpuMesh { - label: model.name.into(), - triangle_indices, - vertex_positions, - vertex_colors, - vertex_normals, - vertex_texcoords, - - // TODO(andreas): proper material loading - materials: smallvec![Material { - label: "default material".into(), - index_range: 0..mesh.indices.len() as u32, - albedo: texture.clone(), - albedo_factor: crate::Rgba::WHITE, - }], - }; - - mesh.sanity_check()?; - - Ok(MeshInstance::new_with_cpu_mesh( - Arc::new(GpuMesh::new(ctx, &mesh)?), - Some(Arc::new(mesh)), - )) - }) - .collect() + let mut model = CpuModel::default(); + for obj_model in models { + // This could be optimized by using bytemuck. + + let mesh = obj_model.mesh; + let vertex_positions: Vec = mesh + .positions + .chunks_exact(3) + .map(|p| glam::vec3(p[0], p[1], p[2])) + .collect(); + + let triangle_indices = mesh + .indices + .chunks_exact(3) + .map(|p| glam::uvec3(p[0], p[1], p[2])) + .collect(); + + let mut vertex_colors: Vec = mesh + .vertex_color + .chunks_exact(3) + .map(|c| { + Rgba32Unmul::from_rgb( + // It is not specified if the color is in linear or gamma space, but gamma seems a safe bet. + (c[0] * 255.0).round() as u8, + (c[1] * 255.0).round() as u8, + (c[2] * 255.0).round() as u8, + ) + }) + .collect(); + vertex_colors.resize(vertex_positions.len(), Rgba32Unmul::WHITE); + + let mut vertex_normals: Vec = mesh + .normals + .chunks_exact(3) + .map(|n| glam::vec3(n[0], n[1], n[2])) + .collect(); + vertex_normals.resize(vertex_positions.len(), glam::Vec3::ZERO); + + let mut vertex_texcoords: Vec = mesh + .texcoords + .chunks_exact(2) + .map(|t| glam::vec2(t[0], t[1])) + .collect(); + vertex_texcoords.resize(vertex_positions.len(), glam::Vec2::ZERO); + + let texture = ctx.texture_manager_2d.white_texture_unorm_handle(); + + let mesh = CpuMesh { + label: obj_model.name.into(), + triangle_indices, + vertex_positions, + vertex_colors, + vertex_normals, + vertex_texcoords, + + // TODO(andreas): proper material loading + materials: smallvec![Material { + label: "default material".into(), + index_range: 0..mesh.indices.len() as u32, + albedo: texture.clone(), + albedo_factor: crate::Rgba::WHITE, + }], + }; + + mesh.sanity_check()?; + model.add_single_instance_mesh(mesh); + } + + Ok(model) } diff --git a/crates/viewer/re_renderer/src/importer/stl.rs b/crates/viewer/re_renderer/src/importer/stl.rs index 8a171b706e37..deca0e7a2ebd 100644 --- a/crates/viewer/re_renderer/src/importer/stl.rs +++ b/crates/viewer/re_renderer/src/importer/stl.rs @@ -1,13 +1,10 @@ -use std::sync::Arc; - use itertools::Itertools; use smallvec::smallvec; use tinystl::StlData; use crate::{ - mesh::{self, GpuMesh}, - renderer::MeshInstance, - RenderContext, + mesh::{self}, + CpuModel, RenderContext, }; #[derive(thiserror::Error, Debug)] @@ -23,7 +20,7 @@ pub enum StlImportError { pub fn load_stl_from_buffer( buffer: &[u8], ctx: &RenderContext, -) -> Result, StlImportError> { +) -> Result { re_tracing::profile_function!(); let cursor = std::io::Cursor::new(buffer); @@ -70,8 +67,5 @@ pub fn load_stl_from_buffer( mesh.sanity_check()?; - Ok(vec![MeshInstance::new_with_cpu_mesh( - Arc::new(GpuMesh::new(ctx, &mesh)?), - Some(Arc::new(mesh)), - )]) + Ok(CpuModel::from_single_mesh(mesh)) } diff --git a/crates/viewer/re_renderer/src/lib.rs b/crates/viewer/re_renderer/src/lib.rs index 371ffcfecd13..72fdade72dd1 100644 --- a/crates/viewer/re_renderer/src/lib.rs +++ b/crates/viewer/re_renderer/src/lib.rs @@ -58,6 +58,7 @@ pub use colormap::{ pub use context::{adapter_info_summary, RenderContext, RenderContextError}; pub use debug_label::DebugLabel; pub use depth_offset::DepthOffset; +pub use importer::{CpuMeshInstance, CpuModel, CpuModelMeshKey}; pub use line_drawable_builder::{LineDrawableBuilder, LineStripBuilder}; pub use point_cloud_builder::{PointCloudBatchBuilder, PointCloudBuilder}; pub use queueable_draw_data::QueueableDrawData; From b3020e60f7bddbe85f683a1ab7d1ae8b85b496b9 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 18 Oct 2024 10:18:13 +0200 Subject: [PATCH 3/7] wire everything up --- .../re_renderer/src/importer/cpu_model.rs | 49 ++++++++++++++++--- crates/viewer/re_renderer/src/importer/mod.rs | 18 ------- .../re_renderer/src/renderer/mesh_renderer.rs | 11 +---- .../viewer/re_renderer_examples/framework.rs | 5 +- .../viewer/re_renderer_examples/multiview.rs | 1 - .../viewer/re_renderer_examples/outlines.rs | 1 - crates/viewer/re_renderer_examples/picking.rs | 1 - .../re_space_view_spatial/src/mesh_loader.rs | 5 +- .../src/visualizers/assets3d.rs | 1 - .../src/visualizers/meshes.rs | 1 - .../visualizers/utilities/proc_mesh_vis.rs | 1 - 11 files changed, 51 insertions(+), 43 deletions(-) diff --git a/crates/viewer/re_renderer/src/importer/cpu_model.rs b/crates/viewer/re_renderer/src/importer/cpu_model.rs index fca16822f815..2f29332c3c8b 100644 --- a/crates/viewer/re_renderer/src/importer/cpu_model.rs +++ b/crates/viewer/re_renderer/src/importer/cpu_model.rs @@ -1,8 +1,11 @@ -use slotmap::SlotMap; +use std::sync::Arc; + +use slotmap::{SecondaryMap, SlotMap}; use crate::{ - mesh::{CpuMesh, MeshError}, + mesh::{CpuMesh, GpuMesh, MeshError}, renderer::MeshInstance, + RenderContext, }; slotmap::new_key_type! { @@ -46,10 +49,44 @@ impl CpuModel { }); } + pub fn calculate_bounding_box(&self) -> re_math::BoundingBox { + re_math::BoundingBox::from_points( + self.instances + .iter() + .filter_map(|mesh_instance| { + self.meshes.get(mesh_instance.mesh).map(|mesh| { + mesh.vertex_positions + .iter() + .map(|p| mesh_instance.world_from_mesh.transform_point3(*p)) + }) + }) + .flatten(), + ) + } + /// Converts the entire model into a serious of mesh instances that can be rendered. - // TODO(andreas): Should offer the option to discard or not discard the original mesh information - // since this can be a significant memory overhead. - pub fn to_gpu() -> Result, MeshError> { - todo!() + /// + /// Silently ignores: + /// * instances with invalid mesh keys + /// * unreferenced meshes + pub fn into_gpu_meshes(self, ctx: &RenderContext) -> Result, MeshError> { + let mut gpu_meshes = SecondaryMap::with_capacity(self.meshes.len()); + for (mesh_key, mesh) in &self.meshes { + gpu_meshes.insert(mesh_key, Arc::new(GpuMesh::new(ctx, mesh)?)); + } + + Ok(self + .instances + .into_iter() + .filter_map(|instance| { + Some(MeshInstance { + gpu_mesh: gpu_meshes.get(instance.mesh)?.clone(), + world_from_mesh: instance.world_from_mesh, + additive_tint: Default::default(), + outline_mask_ids: Default::default(), + picking_layer_id: Default::default(), + }) + }) + .collect()) } } diff --git a/crates/viewer/re_renderer/src/importer/mod.rs b/crates/viewer/re_renderer/src/importer/mod.rs index 5e754cee315a..2e4c3132b3df 100644 --- a/crates/viewer/re_renderer/src/importer/mod.rs +++ b/crates/viewer/re_renderer/src/importer/mod.rs @@ -10,21 +10,3 @@ pub mod gltf; pub mod stl; pub use cpu_model::{CpuMeshInstance, CpuModel, CpuModelMeshKey}; - -use crate::renderer::MeshInstance; - -// TODO: make this part of the cpu model only. -pub fn calculate_bounding_box(instances: &[MeshInstance]) -> re_math::BoundingBox { - re_math::BoundingBox::from_points( - instances - .iter() - .filter_map(|mesh_instance| { - mesh_instance.mesh.as_ref().map(|mesh| { - mesh.vertex_positions - .iter() - .map(|p| mesh_instance.world_from_mesh.transform_point3(*p)) - }) - }) - .flatten(), - ) -} diff --git a/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs b/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs index 6dfd74e21ae1..92e96b55b9d3 100644 --- a/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs +++ b/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs @@ -11,7 +11,7 @@ use smallvec::smallvec; use crate::{ draw_phases::{DrawPhase, OutlineMaskProcessor}, include_shader_module, - mesh::{gpu_data::MaterialUniformBuffer, mesh_vertices, CpuMesh, GpuMesh}, + mesh::{gpu_data::MaterialUniformBuffer, mesh_vertices, GpuMesh}, view_builder::ViewBuilder, wgpu_resources::{ BindGroupLayoutDesc, BufferDesc, GpuBindGroupLayoutHandle, GpuBuffer, @@ -114,9 +114,6 @@ pub struct MeshInstance { /// Gpu mesh used by this instance pub gpu_mesh: Arc, - /// Optional cpu representation of the mesh, not needed for rendering. - pub mesh: Option>, - /// Where this instance is placed in world space and how its oriented & scaled. pub world_from_mesh: glam::Affine3A, @@ -134,14 +131,8 @@ pub struct MeshInstance { impl MeshInstance { /// Creates a new instance of a mesh with all fields set to default except for required ones. pub fn new(gpu_mesh: Arc) -> Self { - Self::new_with_cpu_mesh(gpu_mesh, None) - } - - /// Creates a new instance of a mesh with gpu and optional cpu mesh. - pub fn new_with_cpu_mesh(gpu_mesh: Arc, cpu_mesh: Option>) -> Self { Self { gpu_mesh, - mesh: cpu_mesh, world_from_mesh: glam::Affine3A::IDENTITY, additive_tint: Color32::TRANSPARENT, outline_mask_ids: OutlineMaskPreference::NONE, diff --git a/crates/viewer/re_renderer_examples/framework.rs b/crates/viewer/re_renderer_examples/framework.rs index a034242c9143..bc551c7e87e0 100644 --- a/crates/viewer/re_renderer_examples/framework.rs +++ b/crates/viewer/re_renderer_examples/framework.rs @@ -332,7 +332,10 @@ pub fn load_rerun_mesh(re_ctx: &RenderContext) -> Vec { diff --git a/crates/viewer/re_renderer_examples/multiview.rs b/crates/viewer/re_renderer_examples/multiview.rs index bbc3a06380c9..f419186f727a 100644 --- a/crates/viewer/re_renderer_examples/multiview.rs +++ b/crates/viewer/re_renderer_examples/multiview.rs @@ -37,7 +37,6 @@ fn build_mesh_instances( model_mesh_instances.iter().zip(positions_and_colors).map( move |(model_mesh_instances, (p, c))| MeshInstance { gpu_mesh: model_mesh_instances.gpu_mesh.clone(), - mesh: None, world_from_mesh: glam::Affine3A::from_scale_rotation_translation( glam::vec3( 2.5 + (i % 3) as f32, diff --git a/crates/viewer/re_renderer_examples/outlines.rs b/crates/viewer/re_renderer_examples/outlines.rs index 9b3272f9e091..04b8c9c158f1 100644 --- a/crates/viewer/re_renderer_examples/outlines.rs +++ b/crates/viewer/re_renderer_examples/outlines.rs @@ -112,7 +112,6 @@ impl framework::Example for Outlines { .iter() .map(move |instance| MeshInstance { gpu_mesh: instance.gpu_mesh.clone(), - mesh: None, world_from_mesh: glam::Affine3A::from_rotation_translation( props.rotation, props.position, diff --git a/crates/viewer/re_renderer_examples/picking.rs b/crates/viewer/re_renderer_examples/picking.rs index 45b654b38de2..ffeacf331a31 100644 --- a/crates/viewer/re_renderer_examples/picking.rs +++ b/crates/viewer/re_renderer_examples/picking.rs @@ -178,7 +178,6 @@ impl framework::Example for Picking { .iter() .map(|instance| MeshInstance { gpu_mesh: instance.gpu_mesh.clone(), - mesh: None, world_from_mesh: glam::Affine3A::from_translation(glam::vec3(0.0, 0.0, 0.0)), picking_layer_id: MESH_ID, additive_tint: if self.mesh_is_hovered { diff --git a/crates/viewer/re_space_view_spatial/src/mesh_loader.rs b/crates/viewer/re_space_view_spatial/src/mesh_loader.rs index 33833517e0aa..e34cbcf3ee6e 100644 --- a/crates/viewer/re_space_view_spatial/src/mesh_loader.rs +++ b/crates/viewer/re_space_view_spatial/src/mesh_loader.rs @@ -42,7 +42,7 @@ impl LoadedMesh { ) -> anyhow::Result { re_tracing::profile_function!(); - let mesh_instances = match media_type.as_str() { + let cpu_model = match media_type.as_str() { MediaType::GLTF | MediaType::GLB => { re_renderer::importer::gltf::load_gltf_from_buffer(&name, bytes, render_ctx)? } @@ -51,7 +51,8 @@ impl LoadedMesh { _ => anyhow::bail!("{media_type} files are not supported"), }; - let bbox = re_renderer::importer::calculate_bounding_box(&mesh_instances); + let bbox = cpu_model.calculate_bounding_box(); + let mesh_instances = cpu_model.into_gpu_meshes(render_ctx)?; Ok(Self { name, diff --git a/crates/viewer/re_space_view_spatial/src/visualizers/assets3d.rs b/crates/viewer/re_space_view_spatial/src/visualizers/assets3d.rs index 444c24210293..e4a022a488b1 100644 --- a/crates/viewer/re_space_view_spatial/src/visualizers/assets3d.rs +++ b/crates/viewer/re_space_view_spatial/src/visualizers/assets3d.rs @@ -90,7 +90,6 @@ impl Asset3DVisualizer { MeshInstance { gpu_mesh: mesh_instance.gpu_mesh.clone(), - mesh: None, world_from_mesh, outline_mask_ids, picking_layer_id: picking_layer_id_from_instance_path_hash( diff --git a/crates/viewer/re_space_view_spatial/src/visualizers/meshes.rs b/crates/viewer/re_space_view_spatial/src/visualizers/meshes.rs index 4b1e4fc0c4ad..bf108128e22b 100644 --- a/crates/viewer/re_space_view_spatial/src/visualizers/meshes.rs +++ b/crates/viewer/re_space_view_spatial/src/visualizers/meshes.rs @@ -128,7 +128,6 @@ impl Mesh3DVisualizer { MeshInstance { gpu_mesh: mesh_instance.gpu_mesh.clone(), - mesh: None, world_from_mesh, outline_mask_ids, picking_layer_id: picking_layer_id_from_instance_path_hash( diff --git a/crates/viewer/re_space_view_spatial/src/visualizers/utilities/proc_mesh_vis.rs b/crates/viewer/re_space_view_spatial/src/visualizers/utilities/proc_mesh_vis.rs index b264358e7f3e..0b4b32e94676 100644 --- a/crates/viewer/re_space_view_spatial/src/visualizers/utilities/proc_mesh_vis.rs +++ b/crates/viewer/re_space_view_spatial/src/visualizers/utilities/proc_mesh_vis.rs @@ -223,7 +223,6 @@ where self.solid_instances.push(MeshInstance { gpu_mesh: solid_mesh.gpu_mesh, - mesh: None, world_from_mesh: world_from_instance, outline_mask_ids: ent_context.highlight.index_outline_mask(instance), picking_layer_id: picking_layer_id_from_instance_path_hash( From d05b440d1ad0a2759e42ed9de2f399a661a812f9 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 18 Oct 2024 11:43:19 +0200 Subject: [PATCH 4/7] doc string fixes --- crates/viewer/re_renderer/src/mesh.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/viewer/re_renderer/src/mesh.rs b/crates/viewer/re_renderer/src/mesh.rs index 0c88c8c4774c..fb61b7d8ca3c 100644 --- a/crates/viewer/re_renderer/src/mesh.rs +++ b/crates/viewer/re_renderer/src/mesh.rs @@ -157,7 +157,7 @@ pub enum MeshError { pub struct Material { pub label: DebugLabel, - /// Index range within the owning [`Mesh`] that should be rendered with this material. + /// Index range within the owning [`CpuMesh`] that should be rendered with this material. pub index_range: Range, /// Base color texture, also known as albedo. @@ -190,7 +190,7 @@ pub struct GpuMesh { #[derive(Clone)] pub struct GpuMaterial { - /// Index range within the owning [`Mesh`] that should be rendered with this material. + /// Index range within the owning [`CpuMesh`] that should be rendered with this material. pub index_range: Range, pub bind_group: GpuBindGroup, From c14fb007e9449ec46aa3e636fc593cd0e04f742b Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 22 Oct 2024 12:35:30 +0200 Subject: [PATCH 5/7] rename MeshInstance to GpuMeshInstance to improve clarity, add comment on what a `CpuModel` is and why there's no `GpuModel` --- .../re_renderer/src/importer/cpu_model.rs | 17 ++++++++++------- .../re_renderer/src/renderer/mesh_renderer.rs | 6 +++--- crates/viewer/re_renderer/src/renderer/mod.rs | 2 +- crates/viewer/re_renderer_examples/framework.rs | 2 +- crates/viewer/re_renderer_examples/multiview.rs | 8 ++++---- crates/viewer/re_renderer_examples/outlines.rs | 6 +++--- crates/viewer/re_renderer_examples/picking.rs | 6 +++--- .../re_space_view_spatial/src/mesh_loader.rs | 4 ++-- .../src/visualizers/assets3d.rs | 6 +++--- .../src/visualizers/meshes.rs | 6 +++--- .../src/visualizers/utilities/proc_mesh_vis.rs | 6 +++--- 11 files changed, 36 insertions(+), 33 deletions(-) diff --git a/crates/viewer/re_renderer/src/importer/cpu_model.rs b/crates/viewer/re_renderer/src/importer/cpu_model.rs index 2f29332c3c8b..00cbca9c8985 100644 --- a/crates/viewer/re_renderer/src/importer/cpu_model.rs +++ b/crates/viewer/re_renderer/src/importer/cpu_model.rs @@ -4,7 +4,7 @@ use slotmap::{SecondaryMap, SlotMap}; use crate::{ mesh::{CpuMesh, GpuMesh, MeshError}, - renderer::MeshInstance, + renderer::GpuMeshInstance, RenderContext, }; @@ -13,17 +13,20 @@ slotmap::new_key_type! { pub struct CpuModelMeshKey; } -/// Like [`MeshInstance`], but for CPU sided usage in a [`CpuModel`] only. +/// Like [`GpuMeshInstance`], but for CPU sided usage in a [`CpuModel`] only. pub struct CpuMeshInstance { pub mesh: CpuModelMeshKey, pub world_from_mesh: glam::Affine3A, - // TODO(andreas): Expose other properties we have on [`MeshInstance`]. + // TODO(andreas): Expose other properties we have on [`GpuMeshInstance`]. } -/// A model as stored on the CPU. +/// A collection of meshes & mesh instances on the CPU. +/// +/// Note that there is currently no `GpuModel` equivalent, since +/// [`GpuMeshInstance`]es use shared ownership of [`GpuMesh`]es. /// /// This is the output of a model loader and is ready to be converted into -/// a series of [`MeshInstance`]s that can be rendered. +/// a series of [`GpuMeshInstance`]s that can be rendered. /// /// This is meant as a useful intermediate structure for doing post-processing steps on the model prior to gpu upload. #[derive(Default)] @@ -69,7 +72,7 @@ impl CpuModel { /// Silently ignores: /// * instances with invalid mesh keys /// * unreferenced meshes - pub fn into_gpu_meshes(self, ctx: &RenderContext) -> Result, MeshError> { + pub fn into_gpu_meshes(self, ctx: &RenderContext) -> Result, MeshError> { let mut gpu_meshes = SecondaryMap::with_capacity(self.meshes.len()); for (mesh_key, mesh) in &self.meshes { gpu_meshes.insert(mesh_key, Arc::new(GpuMesh::new(ctx, mesh)?)); @@ -79,7 +82,7 @@ impl CpuModel { .instances .into_iter() .filter_map(|instance| { - Some(MeshInstance { + Some(GpuMeshInstance { gpu_mesh: gpu_meshes.get(instance.mesh)?.clone(), world_from_mesh: instance.world_from_mesh, additive_tint: Default::default(), diff --git a/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs b/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs index 92e96b55b9d3..1162c3890361 100644 --- a/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs +++ b/crates/viewer/re_renderer/src/renderer/mesh_renderer.rs @@ -110,7 +110,7 @@ impl DrawData for MeshDrawData { type Renderer = MeshRenderer; } -pub struct MeshInstance { +pub struct GpuMeshInstance { /// Gpu mesh used by this instance pub gpu_mesh: Arc, @@ -128,7 +128,7 @@ pub struct MeshInstance { pub picking_layer_id: PickingLayerId, } -impl MeshInstance { +impl GpuMeshInstance { /// Creates a new instance of a mesh with all fields set to default except for required ones. pub fn new(gpu_mesh: Arc) -> Self { Self { @@ -149,7 +149,7 @@ impl MeshDrawData { /// Mesh data itself is gpu uploaded if not already present. pub fn new( ctx: &RenderContext, - instances: &[MeshInstance], + instances: &[GpuMeshInstance], ) -> Result { re_tracing::profile_function!(); diff --git a/crates/viewer/re_renderer/src/renderer/mod.rs b/crates/viewer/re_renderer/src/renderer/mod.rs index f29c19da86e3..099754cdff2c 100644 --- a/crates/viewer/re_renderer/src/renderer/mod.rs +++ b/crates/viewer/re_renderer/src/renderer/mod.rs @@ -23,7 +23,7 @@ pub use rectangles::{ mod mesh_renderer; pub(crate) use mesh_renderer::MeshRenderer; -pub use mesh_renderer::{MeshDrawData, MeshInstance}; +pub use mesh_renderer::{MeshDrawData, GpuMeshInstance}; mod compositor; pub(crate) use compositor::CompositorDrawData; diff --git a/crates/viewer/re_renderer_examples/framework.rs b/crates/viewer/re_renderer_examples/framework.rs index bc551c7e87e0..c0fd2433c92e 100644 --- a/crates/viewer/re_renderer_examples/framework.rs +++ b/crates/viewer/re_renderer_examples/framework.rs @@ -326,7 +326,7 @@ impl Application { } #[allow(dead_code)] -pub fn load_rerun_mesh(re_ctx: &RenderContext) -> Vec { +pub fn load_rerun_mesh(re_ctx: &RenderContext) -> Vec { let reader = std::io::Cursor::new(include_bytes!("../../../tests/assets/rerun.obj.zip")); let mut zip = zip::ZipArchive::new(reader).unwrap(); let mut zipped_obj = zip.by_name("rerun.obj").unwrap(); diff --git a/crates/viewer/re_renderer_examples/multiview.rs b/crates/viewer/re_renderer_examples/multiview.rs index f419186f727a..fe19c9abb712 100644 --- a/crates/viewer/re_renderer_examples/multiview.rs +++ b/crates/viewer/re_renderer_examples/multiview.rs @@ -13,7 +13,7 @@ use re_math::IsoTransform; use re_renderer::{ renderer::{ - GenericSkyboxDrawData, LineDrawData, LineStripFlags, MeshDrawData, MeshInstance, + GenericSkyboxDrawData, LineDrawData, LineStripFlags, MeshDrawData, GpuMeshInstance, TestTriangleDrawData, }, view_builder::{OrthographicCameraMode, Projection, TargetConfiguration, ViewBuilder}, @@ -26,7 +26,7 @@ mod framework; fn build_mesh_instances( re_ctx: &RenderContext, - model_mesh_instances: &[MeshInstance], + model_mesh_instances: &[GpuMeshInstance], mesh_instance_positions_and_colors: &[(glam::Vec3, Color32)], seconds_since_startup: f32, ) -> MeshDrawData { @@ -35,7 +35,7 @@ fn build_mesh_instances( .enumerate() .flat_map(|(i, positions_and_colors)| { model_mesh_instances.iter().zip(positions_and_colors).map( - move |(model_mesh_instances, (p, c))| MeshInstance { + move |(model_mesh_instances, (p, c))| GpuMeshInstance { gpu_mesh: model_mesh_instances.gpu_mesh.clone(), world_from_mesh: glam::Affine3A::from_scale_rotation_translation( glam::vec3( @@ -156,7 +156,7 @@ struct Multiview { camera_control: CameraControl, camera_position: glam::Vec3, - model_mesh_instances: Vec, + model_mesh_instances: Vec, mesh_instance_positions_and_colors: Vec<(glam::Vec3, Color32)>, // Want to have a large cloud of random points, but doing rng for all of them every frame is too slow diff --git a/crates/viewer/re_renderer_examples/outlines.rs b/crates/viewer/re_renderer_examples/outlines.rs index 04b8c9c158f1..c640d70d398b 100644 --- a/crates/viewer/re_renderer_examples/outlines.rs +++ b/crates/viewer/re_renderer_examples/outlines.rs @@ -5,7 +5,7 @@ use itertools::Itertools; use re_renderer::{ - renderer::MeshInstance, + renderer::GpuMeshInstance, view_builder::{Projection, TargetConfiguration, ViewBuilder}, Color32, OutlineConfig, OutlineMaskPreference, }; @@ -16,7 +16,7 @@ mod framework; struct Outlines { is_paused: bool, seconds_since_startup: f32, - model_mesh_instances: Vec, + model_mesh_instances: Vec, } struct MeshProperties { @@ -110,7 +110,7 @@ impl framework::Example for Outlines { .flat_map(|props| { self.model_mesh_instances .iter() - .map(move |instance| MeshInstance { + .map(move |instance| GpuMeshInstance { gpu_mesh: instance.gpu_mesh.clone(), world_from_mesh: glam::Affine3A::from_rotation_translation( props.rotation, diff --git a/crates/viewer/re_renderer_examples/picking.rs b/crates/viewer/re_renderer_examples/picking.rs index ffeacf331a31..ea06f9b7e4da 100644 --- a/crates/viewer/re_renderer_examples/picking.rs +++ b/crates/viewer/re_renderer_examples/picking.rs @@ -6,7 +6,7 @@ use itertools::Itertools as _; use rand::Rng; use re_renderer::{ - renderer::MeshInstance, + renderer::GpuMeshInstance, view_builder::{Projection, TargetConfiguration, ViewBuilder}, Color32, GpuReadbackIdentifier, PickingLayerId, PickingLayerInstanceId, PickingLayerProcessor, PointCloudBuilder, RectInt, Size, @@ -24,7 +24,7 @@ struct PointSet { struct Picking { point_sets: Vec, picking_position: glam::UVec2, - model_mesh_instances: Vec, + model_mesh_instances: Vec, mesh_is_hovered: bool, } @@ -176,7 +176,7 @@ impl framework::Example for Picking { let instances = self .model_mesh_instances .iter() - .map(|instance| MeshInstance { + .map(|instance| GpuMeshInstance { gpu_mesh: instance.gpu_mesh.clone(), world_from_mesh: glam::Affine3A::from_translation(glam::vec3(0.0, 0.0, 0.0)), picking_layer_id: MESH_ID, diff --git a/crates/viewer/re_space_view_spatial/src/mesh_loader.rs b/crates/viewer/re_space_view_spatial/src/mesh_loader.rs index e34cbcf3ee6e..39ac2757ca87 100644 --- a/crates/viewer/re_space_view_spatial/src/mesh_loader.rs +++ b/crates/viewer/re_space_view_spatial/src/mesh_loader.rs @@ -14,7 +14,7 @@ pub struct LoadedMesh { // TODO(andreas): We should only have MeshHandles here (which are generated by the MeshManager!) // Can't do that right now because it's too hard to pass the render context through. - pub mesh_instances: Vec, + pub mesh_instances: Vec, bbox: re_math::BoundingBox, } @@ -173,7 +173,7 @@ impl LoadedMesh { }], }; - let mesh_instances = vec![re_renderer::renderer::MeshInstance::new( + let mesh_instances = vec![re_renderer::renderer::GpuMeshInstance::new( std::sync::Arc::new(GpuMesh::new(render_ctx, &mesh)?), )]; diff --git a/crates/viewer/re_space_view_spatial/src/visualizers/assets3d.rs b/crates/viewer/re_space_view_spatial/src/visualizers/assets3d.rs index e4a022a488b1..a80a38d8e112 100644 --- a/crates/viewer/re_space_view_spatial/src/visualizers/assets3d.rs +++ b/crates/viewer/re_space_view_spatial/src/visualizers/assets3d.rs @@ -1,6 +1,6 @@ use re_chunk_store::RowId; use re_log_types::{hash::Hash64, Instance, TimeInt}; -use re_renderer::renderer::MeshInstance; +use re_renderer::renderer::GpuMeshInstance; use re_renderer::RenderContext; use re_types::{ archetypes::Asset3D, @@ -46,7 +46,7 @@ impl Asset3DVisualizer { &mut self, ctx: &QueryContext<'_>, render_ctx: &RenderContext, - instances: &mut Vec, + instances: &mut Vec, ent_context: &SpatialSceneEntityContext<'_>, data: impl Iterator, ) { @@ -88,7 +88,7 @@ impl Asset3DVisualizer { let pose_from_mesh = mesh_instance.world_from_mesh; let world_from_mesh = world_from_pose * pose_from_mesh; - MeshInstance { + GpuMeshInstance { gpu_mesh: mesh_instance.gpu_mesh.clone(), world_from_mesh, outline_mask_ids, diff --git a/crates/viewer/re_space_view_spatial/src/visualizers/meshes.rs b/crates/viewer/re_space_view_spatial/src/visualizers/meshes.rs index bf108128e22b..2246521c4849 100644 --- a/crates/viewer/re_space_view_spatial/src/visualizers/meshes.rs +++ b/crates/viewer/re_space_view_spatial/src/visualizers/meshes.rs @@ -1,6 +1,6 @@ use re_chunk_store::RowId; use re_log_types::{hash::Hash64, Instance, TimeInt}; -use re_renderer::{renderer::MeshInstance, RenderContext}; +use re_renderer::{renderer::GpuMeshInstance, RenderContext}; use re_types::{ archetypes::Mesh3D, components::{ @@ -63,7 +63,7 @@ impl Mesh3DVisualizer { &mut self, ctx: &QueryContext<'_>, render_ctx: &RenderContext, - instances: &mut Vec, + instances: &mut Vec, ent_context: &SpatialSceneEntityContext<'_>, data: impl Iterator>, ) { @@ -126,7 +126,7 @@ impl Mesh3DVisualizer { let entity_from_mesh = mesh_instance.world_from_mesh; let world_from_mesh = world_from_instance * entity_from_mesh; - MeshInstance { + GpuMeshInstance { gpu_mesh: mesh_instance.gpu_mesh.clone(), world_from_mesh, outline_mask_ids, diff --git a/crates/viewer/re_space_view_spatial/src/visualizers/utilities/proc_mesh_vis.rs b/crates/viewer/re_space_view_spatial/src/visualizers/utilities/proc_mesh_vis.rs index 0b4b32e94676..5ca2a280cd4a 100644 --- a/crates/viewer/re_space_view_spatial/src/visualizers/utilities/proc_mesh_vis.rs +++ b/crates/viewer/re_space_view_spatial/src/visualizers/utilities/proc_mesh_vis.rs @@ -1,6 +1,6 @@ use re_entity_db::InstancePathHash; use re_log_types::Instance; -use re_renderer::renderer::MeshInstance; +use re_renderer::renderer::GpuMeshInstance; use re_renderer::{LineDrawableBuilder, PickingLayerInstanceId, RenderContext}; use re_types::components::{self, FillMode}; use re_viewer_context::{ @@ -34,7 +34,7 @@ pub struct ProcMeshDrawableBuilder<'ctx, Fb> { pub line_batch_debug_label: re_renderer::DebugLabel, /// Accumulates triangle mesh instances to render. - pub solid_instances: Vec, + pub solid_instances: Vec, pub query: &'ctx ViewQuery<'ctx>, pub render_ctx: &'ctx RenderContext, @@ -221,7 +221,7 @@ where )); }; - self.solid_instances.push(MeshInstance { + self.solid_instances.push(GpuMeshInstance { gpu_mesh: solid_mesh.gpu_mesh, world_from_mesh: world_from_instance, outline_mask_ids: ent_context.highlight.index_outline_mask(instance), From 448a21d33b6c417c28f9a745283ce6bd5c6a424c Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 22 Oct 2024 12:37:36 +0200 Subject: [PATCH 6/7] use anyhow for `load_rerun_mesh` re_renderer example method --- crates/viewer/re_renderer/src/importer/stl.rs | 5 +---- .../viewer/re_renderer_examples/framework.rs | 18 ++++++++++-------- .../viewer/re_renderer_examples/multiview.rs | 5 +++-- crates/viewer/re_renderer_examples/outlines.rs | 3 ++- crates/viewer/re_renderer_examples/picking.rs | 3 ++- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/crates/viewer/re_renderer/src/importer/stl.rs b/crates/viewer/re_renderer/src/importer/stl.rs index deca0e7a2ebd..51cd42c4f669 100644 --- a/crates/viewer/re_renderer/src/importer/stl.rs +++ b/crates/viewer/re_renderer/src/importer/stl.rs @@ -2,10 +2,7 @@ use itertools::Itertools; use smallvec::smallvec; use tinystl::StlData; -use crate::{ - mesh::{self}, - CpuModel, RenderContext, -}; +use crate::{mesh, CpuModel, RenderContext}; #[derive(thiserror::Error, Debug)] pub enum StlImportError { diff --git a/crates/viewer/re_renderer_examples/framework.rs b/crates/viewer/re_renderer_examples/framework.rs index c0fd2433c92e..751565ad619c 100644 --- a/crates/viewer/re_renderer_examples/framework.rs +++ b/crates/viewer/re_renderer_examples/framework.rs @@ -326,16 +326,18 @@ impl Application { } #[allow(dead_code)] -pub fn load_rerun_mesh(re_ctx: &RenderContext) -> Vec { +pub fn load_rerun_mesh( + re_ctx: &RenderContext, +) -> anyhow::Result> { let reader = std::io::Cursor::new(include_bytes!("../../../tests/assets/rerun.obj.zip")); - let mut zip = zip::ZipArchive::new(reader).unwrap(); - let mut zipped_obj = zip.by_name("rerun.obj").unwrap(); + let mut zip = zip::ZipArchive::new(reader)?; + let mut zipped_obj = zip.by_name("rerun.obj")?; let mut obj_data = Vec::new(); - std::io::Read::read_to_end(&mut zipped_obj, &mut obj_data).unwrap(); - re_renderer::importer::obj::load_obj_from_buffer(&obj_data, re_ctx) - .unwrap() - .into_gpu_meshes(re_ctx) - .unwrap() + std::io::Read::read_to_end(&mut zipped_obj, &mut obj_data)?; + Ok( + re_renderer::importer::obj::load_obj_from_buffer(&obj_data, re_ctx)? + .into_gpu_meshes(re_ctx)?, + ) } struct WrapApp { diff --git a/crates/viewer/re_renderer_examples/multiview.rs b/crates/viewer/re_renderer_examples/multiview.rs index fe19c9abb712..af74feb01fc0 100644 --- a/crates/viewer/re_renderer_examples/multiview.rs +++ b/crates/viewer/re_renderer_examples/multiview.rs @@ -13,7 +13,7 @@ use re_math::IsoTransform; use re_renderer::{ renderer::{ - GenericSkyboxDrawData, LineDrawData, LineStripFlags, MeshDrawData, GpuMeshInstance, + GenericSkyboxDrawData, GpuMeshInstance, LineDrawData, LineStripFlags, MeshDrawData, TestTriangleDrawData, }, view_builder::{OrthographicCameraMode, Projection, TargetConfiguration, ViewBuilder}, @@ -276,7 +276,8 @@ impl Example for Multiview { .map(|_| random_color(&mut rnd)) .collect_vec(); - let model_mesh_instances = crate::framework::load_rerun_mesh(re_ctx); + let model_mesh_instances = + crate::framework::load_rerun_mesh(re_ctx).expect("Failed to load rerun mesh"); let mesh_instance_positions_and_colors = lorenz_points(10.0) .iter() diff --git a/crates/viewer/re_renderer_examples/outlines.rs b/crates/viewer/re_renderer_examples/outlines.rs index c640d70d398b..9df0fab6fbbf 100644 --- a/crates/viewer/re_renderer_examples/outlines.rs +++ b/crates/viewer/re_renderer_examples/outlines.rs @@ -34,7 +34,8 @@ impl framework::Example for Outlines { Self { is_paused: false, seconds_since_startup: 0.0, - model_mesh_instances: crate::framework::load_rerun_mesh(re_ctx), + model_mesh_instances: crate::framework::load_rerun_mesh(re_ctx) + .expect("Failed to load rerun mesh"), } } diff --git a/crates/viewer/re_renderer_examples/picking.rs b/crates/viewer/re_renderer_examples/picking.rs index ea06f9b7e4da..af5ab17de139 100644 --- a/crates/viewer/re_renderer_examples/picking.rs +++ b/crates/viewer/re_renderer_examples/picking.rs @@ -86,7 +86,8 @@ impl framework::Example for Picking { }) .collect_vec(); - let model_mesh_instances = crate::framework::load_rerun_mesh(re_ctx); + let model_mesh_instances = + crate::framework::load_rerun_mesh(re_ctx).expect("Failed to load rerun mesh"); Self { point_sets, From 8f15113a84fc9c22e718c388847bd2377915a37d Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 22 Oct 2024 15:03:22 +0200 Subject: [PATCH 7/7] cargo fmt after refactor --- crates/viewer/re_renderer/src/renderer/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/viewer/re_renderer/src/renderer/mod.rs b/crates/viewer/re_renderer/src/renderer/mod.rs index 099754cdff2c..8bb4421a6708 100644 --- a/crates/viewer/re_renderer/src/renderer/mod.rs +++ b/crates/viewer/re_renderer/src/renderer/mod.rs @@ -23,7 +23,7 @@ pub use rectangles::{ mod mesh_renderer; pub(crate) use mesh_renderer::MeshRenderer; -pub use mesh_renderer::{MeshDrawData, GpuMeshInstance}; +pub use mesh_renderer::{GpuMeshInstance, MeshDrawData}; mod compositor; pub(crate) use compositor::CompositorDrawData;