diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 09dd0f5..556d06f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -29,8 +29,25 @@ jobs:
- name: Run clippy
run: |
- cargo clippy -- -D warnings
+ cargo clippy --all-features -- -D warnings
+ checks:
+ name: Checks
+ strategy:
+ matrix:
+ features: ["--no-default-features", "--features avian2d", "--features avian3d", "--features debug-with-gizmos"]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Install stable toolchain
+ uses: dtolnay/rust-toolchain@stable
+
+ - name: Run clippy
+ run: |
+ cargo check ${{ matrix.features }}
+
tests:
name: Tests
runs-on: ubuntu-latest
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 6a687b2..f6ec892 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -9,7 +9,7 @@ permissions:
id-token: write
jobs:
- deploy:
+ build:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
@@ -23,45 +23,30 @@ jobs:
with:
target: wasm32-unknown-unknown
- - name: Install wasm-bindgen
+ - name: install tools
run: |
- cargo install cargo-quickinstall
- cargo quickinstall wasm-bindgen-cli
+ cargo install wasm-bindgen-cli
+ sudo apt-get install -y binaryen
- name: Build
run: |
- cargo build --target wasm32-unknown-unknown --release --example moving --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/moving.wasm
-
- cargo build --target wasm32-unknown-unknown --release --example lines --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/lines.wasm
-
- cargo build --target wasm32-unknown-unknown --release --example many --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/many.wasm
-
- cargo build --target wasm32-unknown-unknown --release --example gltf --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/gltf.wasm
-
- cargo build --target wasm32-unknown-unknown --release --example random_obstacles --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/random_obstacles.wasm
-
- cargo build --target wasm32-unknown-unknown --release --example auto_navmesh_aabb --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/auto_navmesh_aabb.wasm
-
- cargo build --target wasm32-unknown-unknown --release --example auto_navmesh_primitive --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/auto_navmesh_primitive.wasm
-
- cargo build --target wasm32-unknown-unknown --release --example primitive_3d --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/primitive_3d.wasm
-
- cargo build --target wasm32-unknown-unknown --release --example demo --features bevy/webgl2
- wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/demo.wasm
+ for example in "auto_navmesh_aabb" "auto_navmesh_primitive" "primitive_3d" "demo" "auto_navmesh_avian2d" "auto_navmesh_avian3d" "many" "lines" "moving" "gltf" "random_obstacles"
+ do
+ echo "Building $example"
+ cargo build --target wasm32-unknown-unknown --release --example $example --features "bevy/webgl2,avian2d,avian3d"
+ wasm-bindgen --no-typescript --out-dir wasm --target web target/wasm32-unknown-unknown/release/examples/$example.wasm
+ wasm-opt -Oz wasm/${example}_bg.wasm --output wasm/${example}-opt.wasm
+ rm wasm/${example}_bg.wasm
+ mv wasm/${example}-opt.wasm wasm/${example}_bg.wasm
+ cp wasm/example.html wasm/${example}.html
+ sed -i'' "s/name-of-example/${example}/g" wasm/${example}.html
+ done
- name: Copy Assets
run: cp -r assets wasm/
- name: Copy Screenshots
- run: cp screenshots/* wasm/
+ run: cp -r screenshots wasm/
- name: Setup Pages
uses: actions/configure-pages@v5
@@ -71,6 +56,13 @@ jobs:
with:
path: "wasm"
+ deploy:
+ needs: build
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
diff --git a/Cargo.toml b/Cargo.toml
index 962af30..2943498 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,6 +16,18 @@ categories = ["game-development"]
itertools = "0.13"
tracing = { version = "0.1", optional = true }
+[dependencies.avian2d]
+version = "0.1"
+features = ["2d", "f32", "parry-f32"]
+default-features = false
+optional = true
+
+[dependencies.avian3d]
+version = "0.1"
+features = ["3d", "f32", "parry-f32"]
+default-features = false
+optional = true
+
[dependencies.polyanya]
version = "0.7.1"
@@ -52,5 +64,10 @@ default = ["debug-with-gizmos"]
linuxci = ["bevy/x11"]
debug-with-gizmos = ["bevy/bevy_gizmos"]
-[profile.dev.package."*"]
-opt-level = 3
+[[example]]
+name = "auto_navmesh_avian2d"
+required-features = ["avian2d"]
+
+[[example]]
+name = "auto_navmesh_avian3d"
+required-features = ["avian3d"]
diff --git a/examples/auto_navmesh_aabb.rs b/examples/auto_navmesh_aabb.rs
index 7578fff..6ea38e3 100644
--- a/examples/auto_navmesh_aabb.rs
+++ b/examples/auto_navmesh_aabb.rs
@@ -30,6 +30,7 @@ fn main() {
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
title: "Navmesh with Polyanya".to_string(),
+ fit_canvas_to_parent: true,
..default()
}),
..default()
diff --git a/examples/auto_navmesh_avian2d.rs b/examples/auto_navmesh_avian2d.rs
new file mode 100644
index 0000000..6ee88ce
--- /dev/null
+++ b/examples/auto_navmesh_avian2d.rs
@@ -0,0 +1,225 @@
+use avian2d::{math::*, prelude::*};
+use bevy::{color::palettes, math::vec2, prelude::*, sprite::MaterialMesh2dBundle};
+use rand::Rng;
+use vleue_navigator::prelude::*;
+
+#[derive(Component)]
+enum Obstacle {
+ Peg,
+ Wall,
+}
+
+fn main() {
+ App::new()
+ .add_plugins((
+ DefaultPlugins.set(WindowPlugin {
+ primary_window: Some(Window {
+ title: "Navmesh with Polyanya".to_string(),
+ fit_canvas_to_parent: true,
+ ..default()
+ }),
+ ..default()
+ }),
+ PhysicsPlugins::default().with_length_unit(20.0),
+ VleueNavigatorPlugin,
+ NavmeshUpdaterPlugin::::default(),
+ ))
+ .insert_resource(ClearColor(Color::srgb(0.05, 0.05, 0.1)))
+ .insert_resource(Gravity(Vector::NEG_Y * 9.81 * 100.0))
+ .add_systems(Startup, setup)
+ .add_systems(
+ PreUpdate,
+ (puck_back_to_start, move_puck, display_puck_path),
+ )
+ .insert_resource(NavMeshesDebug(palettes::tailwind::RED_800.into()))
+ .run();
+}
+
+fn setup(
+ mut commands: Commands,
+ mut materials: ResMut>,
+ mut meshes: ResMut>,
+) {
+ commands.spawn(Camera2dBundle::default());
+
+ let square_sprite = Sprite {
+ color: Color::srgb(0.7, 0.7, 0.8),
+ custom_size: Some(Vec2::splat(50.0)),
+ ..default()
+ };
+
+ // Left wall
+ commands.spawn((
+ SpriteBundle {
+ sprite: square_sprite.clone(),
+ transform: Transform::from_xyz(-50.0 * 9.5, 0.0, 0.0)
+ .with_scale(Vec3::new(1.0, 15.0, 1.0)),
+ ..default()
+ },
+ RigidBody::Static,
+ Collider::rectangle(50.0, 50.0),
+ Obstacle::Wall,
+ ));
+ // Right wall
+ commands.spawn((
+ SpriteBundle {
+ sprite: square_sprite,
+ transform: Transform::from_xyz(50.0 * 9.5, 0.0, 0.0)
+ .with_scale(Vec3::new(1.0, 15.0, 1.0)),
+ ..default()
+ },
+ RigidBody::Static,
+ Collider::rectangle(50.0, 50.0),
+ Obstacle::Wall,
+ ));
+
+ let marble_radius = 15.0;
+ let step = 10;
+ let marble_mesh = meshes.add(Circle::new(marble_radius));
+ let marble_material = materials.add(Color::srgb(0.2, 0.7, 0.9));
+
+ for x in (-50..50).step_by(step).skip(1) {
+ for (yi, y) in (-50..50).step_by(step).skip(1).enumerate() {
+ commands.spawn((
+ MaterialMesh2dBundle {
+ mesh: marble_mesh.clone().into(),
+ material: marble_material.clone(),
+ transform: Transform::from_xyz(
+ (x as f32
+ + if yi % 2 == 0 {
+ -(step as f32 / 4.0)
+ } else {
+ step as f32 / 4.0
+ }
+ + rand::thread_rng().gen_range(-1.0..1.0))
+ * 9.5,
+ (y as f32 + rand::thread_rng().gen_range(-1.0..1.0)) * 6.0,
+ 0.0,
+ ),
+ ..default()
+ },
+ RigidBody::Static,
+ Collider::circle(marble_radius as Scalar),
+ Obstacle::Peg,
+ ));
+ }
+ }
+
+ let mesh = meshes.add(Circle::new(5.0));
+ let material = materials.add(Color::srgb(0.7, 0.9, 0.2));
+ for x in (-50..50).step_by(5).skip(1) {
+ let start = Vec3::new(x as f32 * 9.5, 300.0, 0.0);
+ commands.spawn((
+ MaterialMesh2dBundle {
+ mesh: mesh.clone().into(),
+ material: material.clone(),
+ transform: Transform::from_translation(start),
+ ..default()
+ },
+ RigidBody::Dynamic,
+ LinearVelocity(
+ Vec2::new(
+ rand::thread_rng().gen_range(-1.0..1.0),
+ rand::thread_rng().gen_range(-1.0..1.0),
+ )
+ .normalize()
+ * 200.0,
+ ),
+ Collider::circle(5.0 as Scalar),
+ Puck(start),
+ ));
+ }
+
+ commands.spawn(NavMeshBundle {
+ settings: NavMeshSettings {
+ // Define the outer borders of the navmesh.
+ fixed: Triangulation::from_outer_edges(&vec![
+ vec2(-500.0, -500.0),
+ vec2(500.0, -500.0),
+ vec2(500.0, 500.0),
+ vec2(-500.0, 500.0),
+ ]),
+ ..default()
+ },
+ update_mode: NavMeshUpdateMode::Direct,
+ ..default()
+ });
+}
+
+#[derive(Component)]
+struct Puck(Vec3);
+
+fn puck_back_to_start(
+ mut commands: Commands,
+ query: Query<(Entity, Ref, &Puck), Without>,
+ navmeshes: Res>,
+ navmesh: Query<&Handle>,
+) {
+ let Some(navmesh) = navmeshes.get(navmesh.single()) else {
+ return;
+ };
+
+ for (entity, transform, puck) in query.iter() {
+ if transform.translation.y < -300.0 {
+ let Some(path) = navmesh.transformed_path(transform.translation, puck.0) else {
+ continue;
+ };
+
+ if let Some((first, remaining)) = path.path.split_first() {
+ let mut remaining = remaining.to_vec();
+ remaining.reverse();
+
+ commands.entity(entity).insert((
+ RigidBody::Static,
+ Path {
+ current: first.clone(),
+ next: remaining,
+ },
+ ));
+ }
+ }
+ }
+}
+
+#[derive(Component)]
+pub struct Path {
+ current: Vec3,
+ next: Vec,
+}
+
+pub fn move_puck(
+ mut commands: Commands,
+ mut navigator: Query<(&mut Transform, &mut Path, Entity, &mut LinearVelocity)>,
+ time: Res
-
-
diff --git a/wasm/lines.html b/wasm/lines.html
deleted file mode 100644
index 9908357..0000000
--- a/wasm/lines.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-