Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/workflows/parry-ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
- name: Build parry3d SIMD
run: cd crates/parry3d; cargo build --verbose --features simd-stable;
- name: Check serialization
run: cargo check --features bytemuck-serialize,serde-serialize,rkyv-serialize;
run: cargo check --features bytemuck-serialize,serde-serialize,rkyv;
- name: Check enhanced-determinism
run: cargo check --features enhanced-determinism
tests:
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
with:
toolchain: stable
- name: cargo doc
run: cargo doc --workspace --features bytemuck-serialize,serde-serialize,rkyv-serialize,parallel --no-deps --document-private-items
run: cargo doc --workspace --features bytemuck-serialize,serde-serialize,parallel --no-deps --document-private-items # TODO: rkyv
check-benchmarks:
runs-on: ubuntu-latest
steps:
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ private
Cargo.lock
Makefile
.vscode
.idea
.idea
.DS_store
72 changes: 72 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,75 @@
## 0.26.0

### Breaking changes

This release migrates parry from `nalgebra` to `glam` (via the `glamx` crate) for future compatibility with
`rust-gpu`. This is a major breaking change affecting almost all public APIs.

#### Type renames

- `Isometry` → `Pose` (using `glamx::Pose2`/`Pose3`)
- `Rotation` → `Rot2`/`Rot3` (using `glamx::Rot2`/`Rot3`)
- `IsometryOps` → `PoseOps`
- `IsometryOpt` → `PoseOpt`

#### Removed types

- `Point<Real>` - use `Vector` instead. Points and vectors are now unified.
- `UnitVector<Real>` - use `Vector` instead. Normalization is no longer encoded in the type.
- `Translation<Real>` - use `Vector` for translations.

#### Math type changes

- `Vector` is now `glam::Vec2`/`Vec3`/`DVec2`/`DVec3` depending on dimension and precision features
- `Matrix` is now `glam::Mat2`/`Mat3`/`DMat2`/`DMat3`
- The `math` module now re-exports glam types and provides dimension-agnostic aliases

#### API signature changes

- Many functions that previously took `&Point<Real>` or `&Vector<Real>` now take `Vector` by value
- Functions taking `&Isometry<Real>` now take `&Pose` or `Pose` by value
- `HalfSpace::new` now takes `Vector` instead of `Unit<Vector<Real>>`
- Shape constructors like `Segment::new`, `Triangle::new`, `Capsule::new` now take `Vector` instead of `Point`
- `Aabb::mins` and `Aabb::maxs` are now `Vector` instead of `Point<Real>`

#### Migration guide

If your codebase currently relies on `nalgebra`, note that `nalgebra` and `glamx` provide type conversion. Enable the
corresponding features:
- `nalgebra = { version = "0.34", features = [ "convert-glam030" ] }`
- `glamx = { version = "0.1", features = ["nalgebra"] }`
then you can convert between `glam` and `nalgebra` types using `.into()`.

```rust
// Before (nalgebra)
use parry3d::na::{Point3, Vector3, Isometry3, Unit};
let point = Point3::new(1.0, 2.0, 3.0);
let vector = Vector3::new(1.0, 0.0, 0.0);
let normal = Unit::new_normalize(vector);
let pos = Isometry3::translation(1.0, 2.0, 3.0);

// After (glam)
use parry3d::math::{Vector, Pose};
let point = Vector::new(1.0, 2.0, 3.0); // Points are now Vector
let vector = Vector::X;
let normal = vector.normalize(); // No Unit wrapper
let pos = Pose::translation(1.0, 2.0, 3.0);
```

Common patterns:
- `Point3::origin()` → `Vector::ZERO`
- `Vector3::x()` → `Vector::X`
- `point.coords` → just use the vector directly
- `Unit::new_normalize(v)` → `v.normalize()`
- `Isometry3::identity()` → `Pose::IDENTITY`
- `isometry.translation.vector` → `pose.translation`

### Modified

- Re-export `glamx` instead of `nalgebra` as the public linear algebra dependency
- Migrate visual examples from `macroquad` to `kiss3d`
- Renamed `rkyv-serialize` feature to just `rkyv`

## 0.25.3

- Significantly improve performances of `Voxels::combine_voxel_states`.
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ parry3d = { path = "crates/parry3d" }
parry2d-f64 = { path = "crates/parry2d-f64" }
parry3d-f64 = { path = "crates/parry3d-f64" }

#glamx = { path = "../glamx" }
#simba = { path = "../simba" }
#simba = { git = "https://github.com/dimforge/simba", rev = "45a5266eb36ed9d25907e9bf9130cd4ac846a748" }
#nalgebra = { git = "https://github.com/dimforge/nalgebra", rev = "0cf79aef0e6155befc3279a3145f1940822b8377" }
2 changes: 1 addition & 1 deletion Claude.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ cargo build -p parry2d
cd crates/parry3d && cargo build --features simd-stable

# Build with all serialization features
cargo build --features bytemuck-serialize,serde-serialize,rkyv-serialize
cargo build --features bytemuck-serialize,serde-serialize,rkyv

# Build with enhanced determinism (incompatible with SIMD)
cargo build --features enhanced-determinism
Expand Down
22 changes: 9 additions & 13 deletions crates/parry2d-f64/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parry2d-f64"
version = "0.25.3"
version = "0.26.0"
authors = ["Sébastien Crozet <[email protected]>"]

description = "2 dimensional collision detection library in Rust. 64-bit precision version."
Expand All @@ -23,7 +23,7 @@ workspace = true
default = ["required-features", "std", "spade"]
required-features = ["dim2", "f64"]
std = [
"nalgebra/std",
"glamx/std",
"slab",
"simba/std",
"arrayvec/std",
Expand All @@ -37,23 +37,19 @@ f64 = []
serde-serialize = [
"serde",
"serde_arrays",
"nalgebra/serde-serialize",
"glamx/serde",
"arrayvec/serde",
"bitflags/serde",
"hashbrown?/serde",
"spade?/serde",
]
rkyv-serialize = [
"rkyv/validation",
"nalgebra/rkyv-serialize",
"simba/rkyv-serialize",
]
bytemuck-serialize = ["bytemuck", "nalgebra/convert-bytemuck"]
rkyv = ["dep:rkyv", "glamx/rkyv"]
bytemuck-serialize = ["bytemuck", "glamx/bytemuck"]
simd-stable = ["simba/wide", "simd-is-enabled"]
simd-nightly = ["simba/portable_simd", "simd-is-enabled"]
enhanced-determinism = ["simba/libm_force", "indexmap"]
enhanced-determinism = ["simba/libm_force", "indexmap", "glamx/libm"]
parallel = ["rayon"]
alloc = ["nalgebra/alloc", "hashbrown"]
alloc = ["hashbrown"]
spade = ["dep:spade", "alloc"]
improved_fixed_point_support = []

Expand All @@ -74,11 +70,11 @@ num-traits = { version = "0.2", default-features = false }
slab = { version = "0.4", optional = true }
arrayvec = { version = "0.7", default-features = false }
simba = { version = "0.9", default-features = false }
nalgebra = { version = "0.34", default-features = false, features = ["libm", "macros"] }
glamx = { version = "0.1.2", default-features = false, features = ["nostd-libm", "approx"] }
approx = { version = "0.5", default-features = false }
serde = { version = "1.0", optional = true, features = ["derive"] }
serde_arrays = { version = "0.2", optional = true }
rkyv = { version = "0.7.41", optional = true }
rkyv = { version = "0.8", optional = true, default-features = false, features = ["bytecheck", "alloc"] }
num-derive = "0.4"
indexmap = { version = "2", features = ["serde"], optional = true }
hashbrown = { version = "0.16", optional = true, default-features = false, features = [
Expand Down
27 changes: 12 additions & 15 deletions crates/parry2d/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parry2d"
version = "0.25.3"
version = "0.26.0"
authors = ["Sébastien Crozet <[email protected]>"]

description = "2 dimensional collision detection library in Rust."
Expand All @@ -24,7 +24,7 @@ default = ["required-features", "std", "spade"]
required-features = ["dim2", "f32"]
std = [
"alloc",
"nalgebra/std",
"glamx/std",
"slab",
"simba/std",
"arrayvec/std",
Expand All @@ -37,26 +37,22 @@ f32 = []
serde-serialize = [
"serde",
"serde_arrays",
"nalgebra/serde-serialize",
"glamx/serde",
"arrayvec/serde",
"bitflags/serde",
"hashbrown?/serde",
"spade?/serde",
]
rkyv-serialize = [
"rkyv/validation",
"nalgebra/rkyv-serialize",
"simba/rkyv-serialize",
]
bytemuck-serialize = ["bytemuck", "nalgebra/convert-bytemuck"]
rkyv = ["dep:rkyv", "glamx/rkyv"]
bytemuck-serialize = ["bytemuck", "glamx/bytemuck"]
simd-stable = ["simba/wide", "simd-is-enabled"]
simd-nightly = ["simba/portable_simd", "simd-is-enabled"]
enhanced-determinism = ["simba/libm_force", "indexmap"]
enhanced-determinism = ["simba/libm_force", "indexmap", "glamx/libm"]
parallel = ["rayon"]
alloc = ["nalgebra/alloc", "hashbrown"]
alloc = ["hashbrown"]
spade = ["dep:spade", "alloc"]
improved_fixed_point_support = []
encase = [ "dep:encase", "nalgebra/encase" ]
encase = [ "dep:encase", "glamx/encase" ]

# Do not enable this feature directly. It is automatically
# enabled with the "simd-stable" or "simd-nightly" feature.
Expand All @@ -75,11 +71,11 @@ num-traits = { version = "0.2", default-features = false }
slab = { version = "0.4", optional = true }
arrayvec = { version = "0.7", default-features = false }
simba = { version = "0.9", default-features = false }
nalgebra = { version = "0.34", default-features = false, features = ["libm", "macros"] }
glamx = { version = "0.1.2", default-features = false, features = ["nostd-libm", "approx"] }
approx = { version = "0.5", default-features = false }
serde = { version = "1.0", optional = true, features = ["derive"] }
serde_arrays = { version = "0.2", optional = true }
rkyv = { version = "0.7.41", optional = true }
rkyv = { version = "0.8", optional = true, default-features = false, features = ["bytecheck", "alloc"] }
num-derive = "0.4"
indexmap = { version = "2", features = ["serde"], optional = true }
hashbrown = { version = "0.16", optional = true, default-features = false, features = [
Expand All @@ -101,7 +97,8 @@ simba = { version = "0.9", default-features = false }
oorandom = "11"
ptree = "0.4.0"
rand = { version = "0.9" }
macroquad = "0.4.12"
kiss3d = "0.39"
web-time = "1"

[package.metadata.docs.rs]
rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"]
Expand Down
93 changes: 46 additions & 47 deletions crates/parry2d/examples/aabb2d.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
mod common_macroquad2d;
mod utils2d;

extern crate nalgebra as na;

use common_macroquad2d::{draw_polyline, lissajous_2d, mquad_from_na, na_from_mquad};
use macroquad::prelude::*;
use na::Isometry2;
use parry2d::bounding_volume::{Aabb, BoundingVolume};
use kiss3d::prelude::*;
use parry2d::bounding_volume::BoundingVolume;
use parry2d::math::Pose;
use parry2d::shape::Ball;
use utils2d::{draw_aabb2, draw_circle, lissajous_2d};

const RENDER_SCALE: f32 = 30.0;

#[macroquad::main("aabb2d")]
#[kiss3d::main]
async fn main() {
let render_pos = Vec2::new(300.0, 300.0);
let mut window = Window::new("aabb2d").await;
let mut camera = PanZoomCamera2d::new(Vec2::ZERO, 4.0);
let mut scene = SceneNode2d::empty();

let start_time = web_time::Instant::now();

loop {
let elapsed_time = get_time() as f32 * 0.7;
clear_background(BLACK);
while window.render_2d(&mut scene, &mut camera).await {
let elapsed_time = start_time.elapsed().as_secs_f32() * 0.7;

/*
* Initialize the shapes.
*/
let ball1 = Ball::new(0.5);
let ball2 = Ball::new(1.0);

let ball1_pos = na_from_mquad(lissajous_2d(elapsed_time)) * 5f32;
let ball2_pos = Isometry2::identity();
let ball1_pos = lissajous_2d(elapsed_time) * 5f32;
let ball1_pose = Pose::from_translation(ball1_pos);
let ball2_pose = Pose::identity();

/*
* Compute their axis-aligned bounding boxes.
*/
let aabb_ball1 = ball1.aabb(&ball1_pos.into());
let aabb_ball2 = ball2.aabb(&ball2_pos);
let aabb_ball1 = ball1.aabb(&ball1_pose);
let aabb_ball2 = ball2.aabb(&ball2_pose);

// Merge the two boxes.
let bounding_aabb = aabb_ball1.merged(&aabb_ball2);
Expand All @@ -50,52 +52,49 @@ async fn main() {
assert!(bounding_aabb.contains(&aabb_ball2));
assert!(loose_aabb_ball2.contains(&aabb_ball2));

let ball1_translation = mquad_from_na(ball1_pos.coords.into()) * RENDER_SCALE + render_pos;
draw_circle(
ball1_translation.x,
ball1_translation.y,
&mut window,
ball1_pos * RENDER_SCALE,
ball1.radius * RENDER_SCALE,
color,
);
let ball2_translation =
mquad_from_na(ball2_pos.translation.vector.into()) * RENDER_SCALE + render_pos;
draw_circle(
ball2_translation.x,
ball2_translation.y,
&mut window,
ball2_pose.translation * RENDER_SCALE,
ball2.radius * RENDER_SCALE,
color,
);

draw_aabb(aabb_ball1, render_pos, color);
draw_aabb(aabb_ball2, render_pos, color);
draw_aabb(bounding_aabb, render_pos, YELLOW);
draw_aabb2(
&mut window,
aabb_ball1.mins * RENDER_SCALE,
aabb_ball1.maxs * RENDER_SCALE,
color,
);
draw_aabb2(
&mut window,
aabb_ball2.mins * RENDER_SCALE,
aabb_ball2.maxs * RENDER_SCALE,
color,
);
draw_aabb2(
&mut window,
bounding_aabb.mins * RENDER_SCALE,
bounding_aabb.maxs * RENDER_SCALE,
YELLOW,
);

// Inclusion test
let color_included: Color = if loose_aabb_ball2.contains(&aabb_ball1) {
BLUE
} else {
MAGENTA
};
draw_aabb(loose_aabb_ball2, render_pos, color_included);
next_frame().await
draw_aabb2(
&mut window,
loose_aabb_ball2.mins * RENDER_SCALE,
loose_aabb_ball2.maxs * RENDER_SCALE,
color_included,
);
}
}

fn draw_aabb(aabb: Aabb, offset: Vec2, color: Color) {
let mins = mquad_from_na(aabb.mins) * RENDER_SCALE + offset;
let maxs = mquad_from_na(aabb.maxs) * RENDER_SCALE + offset;

let line = vec![
Vec2::new(mins.x, mins.y),
Vec2::new(mins.x, maxs.y),
Vec2::new(maxs.x, maxs.y),
Vec2::new(maxs.x, mins.y),
Vec2::new(mins.x, mins.y),
];
let drawable_line = line
.iter()
.zip(line.iter().cycle().skip(1).take(line.len()))
.map(|item| (item.0.clone(), item.1.clone()))
.collect();
draw_polyline(drawable_line, color);
}
Loading