Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 70 additions & 16 deletions crates/rapier3d-meshloader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
#![deny(missing_docs)]

pub use mesh_loader;
use mesh_loader::{Material, Mesh};
use mesh_loader::{Material, Mesh, Scene};
use rapier3d::geometry::{MeshConverter, SharedShape};
use rapier3d::math::{Pose, Vector};
use rapier3d::prelude::MeshConverterError;
use std::path::Path;
use std::path::{Path, PathBuf};

/// The result of loading a shape.
pub struct LoadedShape {
Expand Down Expand Up @@ -35,24 +35,12 @@ pub enum MeshLoaderError {
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>,
fn load_from_scene(
scene: Scene,
converter: &MeshConverter,
scale: Vector,
) -> Result<Vec<Result<LoadedShape, MeshConverterError>>, MeshLoaderError> {
let loader = mesh_loader::Loader::default();
let mut colliders = vec![];
let scene = loader.load(path)?;
// mesh-loader's OBJ backend aligns `scene.materials[i]` with
// `scene.meshes[i]` (it expands per-mesh from the material_index),
// so zipping is correct here. STL produces empty materials; pair
Expand All @@ -72,6 +60,72 @@ pub fn load_from_path(
Ok(colliders)
}

/// 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,
) -> Result<Vec<Result<LoadedShape, MeshConverterError>>, MeshLoaderError> {
let loader = mesh_loader::Loader::default();
let scene = loader.load(path)?;
load_from_scene(scene, converter, scale)
}

/// All supported file types
pub enum FileType {
/// The STL file format
Stl,
/// The OBJ file format
Obj,
/// The COLLADA file format
Collada,
}
impl FileType {
fn extension(&self) -> &'static str {
match self {
FileType::Stl => "stl",
FileType::Obj => "obj",
FileType::Collada => "dae",
}
}
}

/// Loads parry shapes from a file.
///
/// # Parameters
/// - `bytes`: a slice of byetes containing the model data.
/// - `file_type`: the file type of the model.
/// - `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_slice(
bytes: &[u8],
file_type: FileType,
converter: &MeshConverter,
scale: Vector,
) -> Result<Vec<Result<LoadedShape, MeshConverterError>>, MeshLoaderError> {
let loader = mesh_loader::Loader::default();
// TODO: remove this path hack
// requires mesh-loader to fix https://github.com/openrr/mesh-loader/issues/88
let path = PathBuf::new()
.with_file_name("FakeFile")
.with_extension(file_type.extension());
let scene = loader.load_from_slice(bytes, path)?;
load_from_scene(scene, converter, scale)
}

/// Loads an file as a shape from a preloaded raw [`mesh_loader::Mesh`].
///
/// # Parameters
Expand Down