diff --git a/crates/parry2d/examples/aabb2d.rs b/crates/parry2d/examples/aabb2d.rs index 9223f6e5..a105f72b 100644 --- a/crates/parry2d/examples/aabb2d.rs +++ b/crates/parry2d/examples/aabb2d.rs @@ -10,7 +10,7 @@ use parry2d::shape::Ball; const RENDER_SCALE: f32 = 30.0; -#[macroquad::main("parry2d::utils::point_in_poly2d")] +#[macroquad::main("aabb2d")] async fn main() { let render_pos = Vec2::new(300.0, 300.0); diff --git a/crates/parry2d/examples/bounding_sphere2d.rs b/crates/parry2d/examples/bounding_sphere2d.rs index b5a495f1..1785496c 100644 --- a/crates/parry2d/examples/bounding_sphere2d.rs +++ b/crates/parry2d/examples/bounding_sphere2d.rs @@ -10,7 +10,7 @@ use parry2d::shape::Cuboid; const RENDER_SCALE: f32 = 30.0; -#[macroquad::main("parry2d::utils::point_in_poly2d")] +#[macroquad::main("bounding_sphere2d")] async fn main() { let render_pos = Vec2::new(300.0, 300.0); diff --git a/crates/parry2d/examples/convex_hull2d.rs b/crates/parry2d/examples/convex_hull2d.rs index 33b3c3ff..85e8fdc9 100644 --- a/crates/parry2d/examples/convex_hull2d.rs +++ b/crates/parry2d/examples/convex_hull2d.rs @@ -9,7 +9,7 @@ use parry2d::transformation; const RENDER_SCALE: f32 = 30.0; -#[macroquad::main("parry2d::utils::point_in_poly2d")] +#[macroquad::main("convex_hull2d")] async fn main() { let count = 9; let mut pts = vec![Point2::default(); count]; diff --git a/crates/parry2d/examples/point_in_poly2d.rs b/crates/parry2d/examples/point_in_poly2d.rs index 6abc37a8..c0e5cfd7 100644 --- a/crates/parry2d/examples/point_in_poly2d.rs +++ b/crates/parry2d/examples/point_in_poly2d.rs @@ -7,7 +7,7 @@ use parry2d::utils::point_in_poly2d; const RENDER_SCALE: f32 = 30.0; -#[macroquad::main("parry2d::utils::point_in_poly2d")] +#[macroquad::main("points_in_poly2d")] async fn main() { let mut spikes = spikes_polygon(); let mut squares = squares_polygon(); diff --git a/crates/parry2d/examples/polygons_intersection2d.rs b/crates/parry2d/examples/polygons_intersection2d.rs index 604f86c5..4cbeb137 100644 --- a/crates/parry2d/examples/polygons_intersection2d.rs +++ b/crates/parry2d/examples/polygons_intersection2d.rs @@ -8,7 +8,7 @@ use parry2d::transformation::polygons_intersection_points; const RENDER_SCALE: f32 = 30.0; -#[macroquad::main("parry2d::utils::polygons_intersection_points")] +#[macroquad::main("polygons_intersection2d")] async fn main() { let spikes = spikes_polygon(); let mut animated_spikes = spikes.clone(); diff --git a/crates/parry2d/examples/project_point2d.rs b/crates/parry2d/examples/project_point2d.rs index f65a9518..ba615a0f 100644 --- a/crates/parry2d/examples/project_point2d.rs +++ b/crates/parry2d/examples/project_point2d.rs @@ -7,7 +7,7 @@ use parry2d::math::{Isometry, Translation}; use parry2d::query::PointQuery; use parry2d::shape::{Cuboid, TriMesh, TriMeshFlags}; -#[macroquad::main("parry3d::query::PlaneIntersection")] +#[macroquad::main("project_point2d")] async fn main() { // // This is useful to test for https://github.com/dimforge/parry/pull/248 diff --git a/crates/parry2d/examples/raycasts_animated.rs b/crates/parry2d/examples/raycasts_animated.rs index ddd8fcb4..19999653 100644 --- a/crates/parry2d/examples/raycasts_animated.rs +++ b/crates/parry2d/examples/raycasts_animated.rs @@ -9,7 +9,7 @@ use parry2d::shape::Cuboid; const RENDER_SCALE: f32 = 30.0; -#[macroquad::main("parry2d::query::RayCast")] +#[macroquad::main("raycasts_animated")] async fn main() { let animation_scale = 1.4; let animation_rotation = 0.04; diff --git a/crates/parry3d/Cargo.toml b/crates/parry3d/Cargo.toml index 030fdee1..50d3d9cc 100644 --- a/crates/parry3d/Cargo.toml +++ b/crates/parry3d/Cargo.toml @@ -208,3 +208,9 @@ doc-scrape-examples = true name = "time_of_impact_query3d" path = "examples/time_of_impact_query3d.rs" doc-scrape-examples = true + +[[example]] +name = "convex_decomposition" +path = "examples/convex_decomposition.rs" +doc-scrape-examples = true +required-features = ["wavefront"] diff --git a/crates/parry3d/examples/aabb3d.rs b/crates/parry3d/examples/aabb3d.rs index 87101e6b..ef9c411c 100644 --- a/crates/parry3d/examples/aabb3d.rs +++ b/crates/parry3d/examples/aabb3d.rs @@ -8,7 +8,7 @@ use na::Isometry3; use parry3d::bounding_volume::{Aabb, BoundingVolume}; use parry3d::shape::Ball; -#[macroquad::main("parry2d::utils::point_in_poly2d")] +#[macroquad::main("aabb3d")] async fn main() { let camera_pos = Vec3::new(8f32, 8f32, 12f32); diff --git a/crates/parry3d/examples/bounding_sphere3d.rs b/crates/parry3d/examples/bounding_sphere3d.rs index 889085ea..0d3a4d82 100644 --- a/crates/parry3d/examples/bounding_sphere3d.rs +++ b/crates/parry3d/examples/bounding_sphere3d.rs @@ -10,7 +10,7 @@ use na::{Isometry3, Vector3}; use parry3d::bounding_volume::BoundingVolume; use parry3d::shape::Cuboid; -#[macroquad::main("parry2d::utils::point_in_poly2d")] +#[macroquad::main("bounding_sphere3d")] async fn main() { let camera_pos = Vec3::new(8f32, 8f32, 12f32); diff --git a/crates/parry3d/examples/common_macroquad3d.rs b/crates/parry3d/examples/common_macroquad3d.rs index 093a8710..bd3617fa 100644 --- a/crates/parry3d/examples/common_macroquad3d.rs +++ b/crates/parry3d/examples/common_macroquad3d.rs @@ -29,6 +29,20 @@ pub fn na_from_mquad(a: Vec3) -> Point3 { Point3::new(a.x, a.y, a.z) } +/// Converts a hue (from 0..=1) to rgb +#[allow(dead_code)] +pub fn hue_to_rgb(h: f32) -> (f32, f32, f32) { + let kr = (5.0 + h * 6.0).rem_euclid(6.0); + let kg = (3.0 + h * 6.0).rem_euclid(6.0); + let kb = (1.0 + h * 6.0).rem_euclid(6.0); + + let r = 1.0 - kr.min(4.0 - kr).min(1.0).max(0.0); + let g = 1.0 - kg.min(4.0 - kg).min(1.0).max(0.0); + let b = 1.0 - kb.min(4.0 - kb).min(1.0).max(0.0); + + (r, g, b) +} + /// Returns [lissajous curve](https://en.wikipedia.org/wiki/Lissajous_curve) coordinates for time `t`. /// /// This uses hardcoded parameters to have an arbitrary pleasing trajectory. diff --git a/crates/parry3d/examples/convex_decomposition.rs b/crates/parry3d/examples/convex_decomposition.rs new file mode 100644 index 00000000..65daafab --- /dev/null +++ b/crates/parry3d/examples/convex_decomposition.rs @@ -0,0 +1,102 @@ +mod common_macroquad3d; + +extern crate nalgebra as na; + +use common_macroquad3d::{easy_draw_text, hue_to_rgb, mquad_mesh_from_points}; +use macroquad::prelude::*; +use na::Point3; +use obj::{Obj, ObjData}; +use parry3d::{ + math::Real, + shape::{SharedShape, TriMesh, TriMeshFlags}, +}; + +#[macroquad::main("convex_decomposition")] +async fn main() { + /* + * Initialize the shapes. + */ + let Obj { + data: ObjData { + position, objects, .. + }, + .. + } = Obj::load("assets/tests/low_poly_bunny.obj").unwrap(); + + let bunny_mesh = TriMesh::with_flags( + position + .iter() + .map(|v| Point3::new(v[0] as Real, v[1] as Real, v[2] as Real)) + .collect::>(), + objects[0].groups[0] + .polys + .iter() + .map(|p| [p.0[0].0 as u32, p.0[1].0 as u32, p.0[2].0 as u32]) + .collect::>(), + TriMeshFlags::all(), + ) + .unwrap(); + clear_background(BLACK); + + easy_draw_text("Please wait while convex decomposition is being computed..."); + #[cfg(debug_assertions)] + { + macroquad::text::draw_text( + "Running in debug mode is significantly slower than with `--release`.", + 10.0, + 48.0 + 48.0, + 26.0, + RED, + ); + } + next_frame().await; + let mesh_vertices = bunny_mesh.vertices(); + let mesh_indices = bunny_mesh.indices(); + let convex_mesh = SharedShape::convex_decomposition(&mesh_vertices, &mesh_indices); + let trimesh_convex_compound = convex_mesh.as_compound().unwrap(); + + let shapes_count = trimesh_convex_compound.shapes().len() as u32; + let mut meshes = Vec::new(); + for (i, s) in trimesh_convex_compound.shapes().iter().enumerate() { + let trimesh_convex = s.1.as_convex_polyhedron().unwrap().to_trimesh(); + + /* + * Make render meshes out of the shapes. + */ + let (r, g, b) = hue_to_rgb(i as f32 / 6 as f32); + let mesh = mquad_mesh_from_points( + &trimesh_convex, + Vec3::new(1f32, 3f32, 3f32), + Color::from_rgba( + (r as f32 * 255.0) as u8, + (g as f32 * 255.0) as u8, + (b as f32 * 255.0) as u8, + 255, + ), + ); + meshes.push(mesh); + } + + loop { + clear_background(BLACK); + let elapsed_time = get_time() as f32; + let camera_pos = Vec3::new( + 5.5f32 * elapsed_time.sin(), + 3f32, + 5.5f32 * elapsed_time.cos(), + ); + // Initialize 3D camera. + set_camera(&Camera3D { + position: camera_pos, + up: Vec3::new(0f32, 1f32, 0f32), + target: Vec3::new(0f32, 1f32, 0f32), + ..Default::default() + }); + for mesh in &meshes { + draw_mesh(mesh); + } + set_default_camera(); + easy_draw_text(&format!("Number of shapes: {}", shapes_count)); + next_frame().await + } +} diff --git a/crates/parry3d/examples/convex_hull3d.rs b/crates/parry3d/examples/convex_hull3d.rs index 32d2fcc5..7b009605 100644 --- a/crates/parry3d/examples/convex_hull3d.rs +++ b/crates/parry3d/examples/convex_hull3d.rs @@ -9,7 +9,7 @@ use macroquad::prelude::*; use nalgebra::Point3; use parry3d::transformation; -#[macroquad::main("parry2d::utils::point_in_poly2d")] +#[macroquad::main("convex_hull3d")] async fn main() { let count = 9; let mut pts = vec![Point3::default(); count]; diff --git a/crates/parry3d/examples/plane_intersection.rs b/crates/parry3d/examples/plane_intersection.rs index 2d7f284f..c7420787 100644 --- a/crates/parry3d/examples/plane_intersection.rs +++ b/crates/parry3d/examples/plane_intersection.rs @@ -6,7 +6,7 @@ use parry3d::shape::{Cuboid, TriMesh}; mod common_macroquad3d; use common_macroquad3d::*; -#[macroquad::main("parry3d::query::PlaneIntersection")] +#[macroquad::main("plane_intersection")] async fn main() { let trimesh = Cuboid::new(Vector3::repeat(1.0)).to_trimesh(); diff --git a/crates/parry3d/examples/project_point3d.rs b/crates/parry3d/examples/project_point3d.rs index ac3025af..c629030b 100644 --- a/crates/parry3d/examples/project_point3d.rs +++ b/crates/parry3d/examples/project_point3d.rs @@ -6,7 +6,7 @@ use parry3d::shape::{Cuboid, TriMesh, TriMeshFlags}; mod common_macroquad3d; use common_macroquad3d::*; -#[macroquad::main("parry3d::query::PlaneIntersection")] +#[macroquad::main("project_point3d")] async fn main() { let trimesh = Cuboid::new(Vector3::new(0.2, 0.5, 1.0)).to_trimesh();