use crate::prelude::*;
use avian2d::{
parry::{
math::{Isometry, Point, Real},
shape::SharedShape,
},
prelude::*,
};
use bevy::prelude::*;
#[derive(Default, Reflect, Copy, Clone, Debug)]
#[reflect(Default, Debug)]
pub enum TiledPhysicsAvianBackend {
#[default]
Polyline,
Triangulation,
LineStrip,
}
impl TiledPhysicsBackend for TiledPhysicsAvianBackend {
fn spawn_colliders(
&self,
commands: &mut Commands,
source: &TiledEvent<ColliderCreated>,
multi_polygon: &geo::MultiPolygon<f32>,
) -> Vec<Entity> {
let mut out = vec![];
match self {
TiledPhysicsAvianBackend::Triangulation => {
let shared_shapes = multi_polygon_as_triangles(multi_polygon)
.iter()
.map(|([a, b, c], centroid)| {
(
Isometry::<Real>::new((*centroid).into(), 0.),
SharedShape::triangle((*a).into(), (*b).into(), (*c).into()),
)
})
.collect::<Vec<_>>();
if !shared_shapes.is_empty() {
let collider: Collider = SharedShape::compound(shared_shapes).into();
out.push(
commands
.spawn((
Name::from("Avian[Triangulation]"),
ChildOf(*source.event.collider_of),
collider,
))
.id(),
);
}
}
TiledPhysicsAvianBackend::LineStrip => {
multi_polygon_as_line_strings(multi_polygon)
.iter()
.enumerate()
.for_each(|(i, ls)| {
let collider: Collider = SharedShape::polyline(
ls.points().map(|v| Point::new(v.x(), v.y())).collect(),
None,
)
.into();
out.push(
commands
.spawn((
Name::from(format!("Avian[LineStrip {i}]")),
ChildOf(*source.event.collider_of),
collider,
))
.id(),
);
});
}
TiledPhysicsAvianBackend::Polyline => {
let mut vertices = vec![];
let mut indices = vec![];
multi_polygon_as_line_strings(multi_polygon)
.iter()
.for_each(|ls| {
ls.lines().for_each(|l| {
let points = l.points();
let len = vertices.len();
vertices.push(Point::new(points.0.x(), points.0.y()));
vertices.push(Point::new(points.1.x(), points.1.y()));
indices.push([len as u32, (len + 1) as u32]);
});
});
if !vertices.is_empty() {
let collider: Collider = SharedShape::polyline(vertices, Some(indices)).into();
out.push(
commands
.spawn((
Name::from("Avian[Polyline]"),
ChildOf(*source.event.collider_of),
collider,
))
.id(),
);
}
}
}
out
}
}