#![doc = include_str!("../README.md")]
#![deny(missing_docs)]
pub use mesh_loader;
use mesh_loader::{Material, Mesh};
use rapier3d::geometry::{MeshConverter, SharedShape};
use rapier3d::math::{Pose, Vector};
use rapier3d::prelude::MeshConverterError;
use std::path::Path;
pub struct LoadedShape {
pub shape: SharedShape,
pub pose: Pose,
pub raw_mesh: Mesh,
pub material: Material,
}
#[derive(thiserror::Error, Debug)]
pub enum MeshLoaderError {
#[error(transparent)]
MeshConverter(#[from] MeshConverterError),
#[error(transparent)]
Io(#[from] std::io::Error),
}
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 mut colliders = vec![];
let scene = loader.load(path)?;
let mut materials = scene.materials.into_iter();
for raw_mesh in scene.meshes.into_iter() {
let material = materials.next().unwrap_or_default();
let shape = load_from_raw_mesh(&raw_mesh, converter, scale);
colliders.push(shape.map(|(shape, pose)| LoadedShape {
shape,
pose,
raw_mesh,
material,
}));
}
Ok(colliders)
}
pub fn load_from_raw_mesh(
raw_mesh: &Mesh,
converter: &MeshConverter,
scale: Vector,
) -> Result<(SharedShape, Pose), MeshConverterError> {
let vertices: Vec<_> = raw_mesh
.vertices
.iter()
.map(|xyz| Vector::new(xyz[0], xyz[1], xyz[2]) * scale)
.collect();
let indices: Vec<_> = raw_mesh.faces.clone();
converter.convert(vertices, indices)
}