diff options
| author | Thierry Berger <contact@thierryberger.com> | 2024-11-12 09:02:55 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-12 09:02:55 +0100 |
| commit | 71f65fe55a5918a721252a1f7bb74531137ee665 (patch) | |
| tree | 9fc460a012f5846bb62651486a431eea192cebb4 /crates/rapier3d-meshloader/src | |
| parent | 0d791eb794d616c983145853e9c7594baef8f66c (diff) | |
| download | rapier-71f65fe55a5918a721252a1f7bb74531137ee665.tar.gz rapier-71f65fe55a5918a721252a1f7bb74531137ee665.tar.bz2 rapier-71f65fe55a5918a721252a1f7bb74531137ee665.zip | |
Use meshloader to support multiple file formats loading (#744)
Co-authored-by: Tin Lai <tin@tinyiu.com>
Diffstat (limited to 'crates/rapier3d-meshloader/src')
| -rw-r--r-- | crates/rapier3d-meshloader/src/lib.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/crates/rapier3d-meshloader/src/lib.rs b/crates/rapier3d-meshloader/src/lib.rs new file mode 100644 index 0000000..32051e5 --- /dev/null +++ b/crates/rapier3d-meshloader/src/lib.rs @@ -0,0 +1,86 @@ +#![doc = include_str!("../README.md")] +#![deny(missing_docs)] + +use mesh_loader::Mesh; +use rapier3d::geometry::{MeshConverter, SharedShape}; +use rapier3d::math::{Isometry, Point, Real, Vector}; +use rapier3d::prelude::MeshConverterError; +use std::path::Path; + +/// The result of loading a shape. +pub struct LoadedShape { + /// The shape loaded from the file and converted by the [`MeshConverter`]. + pub shape: SharedShape, + /// The shape’s pose. + pub pose: Isometry<Real>, + /// The raw mesh read from the file without any modification. + pub raw_mesh: Mesh, +} + +/// Error while loading an STL file. +#[derive(thiserror::Error, Debug)] +pub enum MeshLoaderError { + /// An error triggered by rapier’s [`MeshConverter`]. + #[error(transparent)] + MeshConverter(#[from] MeshConverterError), + /// A generic IO error. + #[error(transparent)] + Io(#[from] std::io::Error), +} + +/// Loads parry shapes from a file. +/// +/// # Parameters +/// - `path`: the file’s path. +/// - `converter`: controls how the shapes are computed from the content. In particular, it lets +/// you specify if the computed [`SharedShape`] is a triangle mesh, its convex hull, +/// bounding box, etc. +/// - `scale`: the scaling factor applied to the geometry input to the `converter`. This scale will +/// affect at the geometric level the [`LoadedShape::shape`]. Note that raw mesh value stored +/// in [`LoadedShape::raw_mesh`] remains unscaled. +pub fn load_from_path( + path: impl AsRef<Path>, + converter: &MeshConverter, + scale: Vector<Real>, +) -> Result<Vec<Result<LoadedShape, MeshConverterError>>, MeshLoaderError> { + let loader = mesh_loader::Loader::default(); + let mut colliders = vec![]; + let scene = loader.load(path)?; + for (raw_mesh, _) in scene.meshes.into_iter().zip(scene.materials) { + let shape = load_from_raw_mesh(&raw_mesh, converter, scale); + + colliders.push(shape.map(|(shape, pose)| LoadedShape { + shape, + pose, + raw_mesh, + })); + } + Ok(colliders) +} + +/// Loads an file as a shape from a preloaded raw [`mesh_loader::Mesh`]. +/// +/// # Parameters +/// - `raw_mesh`: the raw mesh. +/// - `converter`: controls how the shape is computed from the STL content. In particular, it lets +/// you specify if the computed [`SharedShape`] is a triangle mesh, its convex hull, +/// bounding box, etc. +/// - `scale`: the scaling factor applied to the geometry input to the `converter`. This scale will +/// affect at the geometric level the [`LoadedShape::shape`]. Note that raw mesh value stored +/// in [`LoadedShape::raw_mesh`] remains unscaled. +pub fn load_from_raw_mesh( + raw_mesh: &Mesh, + converter: &MeshConverter, + scale: Vector<Real>, +) -> Result<(SharedShape, Isometry<Real>), MeshConverterError> { + let mut vertices: Vec<_> = raw_mesh + .vertices + .iter() + .map(|xyz| Point::new(xyz[0], xyz[1], xyz[2])) + .collect(); + vertices + .iter_mut() + .for_each(|pt| pt.coords.component_mul_assign(&scale)); + let indices: Vec<_> = raw_mesh.faces.clone(); + converter.convert(vertices, indices) +} |
