Skip to content

Commit

Permalink
Collider scale (#189)
Browse files Browse the repository at this point in the history
# Objective

Depends on #154, which needs to be merged first.

Currently, modifying the transform scale of an entity has no effect on its collider. This means that people need to set the collider size to match the size of the scaled mesh, which is often inconvenient. Colliders should get scaled by their transforms like in other game engines such as Godot, Unity and so on.

## Solution

Extend `Collider` to support scaling:

```rust
pub struct Collider {
    /// The raw unscaled collider shape.
    shape: SharedShape,
    /// The scaled version of the collider shape.
    ///
    /// If the scale is `Vector::ONE`, this will be `None` and `unscaled_shape`
    /// will be used instead.
    scaled_shape: SharedShape,
    /// The global scale used for the collider shape.
    scale: Vector,
}
```

Transform scale works in hierarchies the same way as it does for meshes, so scale is propagated to children.

---

## Migration Guide

This:

```rust
let mesh = meshes.add(Mesh::from(shape::Cube { size: 1.0 }));
commands.spawn((
    PbrBundle {
        mesh,
        transform: Transform::from_scale(Vec3::new(10.0, 1.0, 10.0)),
        ..default()
    },
    Collider::cuboid(10.0, 1.0, 10.0),
    RigidBody::Static,
));
```

becomes this: (collider size matches unscaled mesh size)

```rust
let mesh = meshes.add(Mesh::from(shape::Cube { size: 1.0 }));
commands.spawn((
    PbrBundle {
        mesh,
        transform: Transform::from_scale(Vec3::new(10.0, 1.0, 10.0)),
        ..default()
    },
    Collider::cuboid(1.0, 1.0, 1.0),
    RigidBody::Static,
));
```
  • Loading branch information
Jondolf authored Oct 21, 2023
1 parent 53609b4 commit 3bd7e0e
Show file tree
Hide file tree
Showing 17 changed files with 369 additions and 84 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_xpbd_2d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ glam = { version = "0.24", features = ["approx"] }
derive_more = "0.99"
indexmap = "2.0.0"
fxhash = "0.2.1"
itertools = "0.11"

[dev-dependencies]
examples_common_2d = { path = "../examples_common_2d" }
approx = "0.5"
insta = "1.0"
itertools = "0.10"

[[example]]
name = "chain_2d"
Expand Down
14 changes: 5 additions & 9 deletions crates/bevy_xpbd_2d/examples/chain_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,11 @@ fn follow_mouse(
let (camera, camera_transform) = camera.single();
let mut follower_position = follower.single_mut();

// Set position of follower to cursor position in world coordinates
// https://bevy-cheatbook.github.io/cookbook/cursor2world.html
if let Some(pos) = window.cursor_position() {
let window_size = Vec2::new(window.width(), window.height());
let ndc = (pos / window_size) * 2.0 - Vec2::ONE;
let ndc_to_world =
camera_transform.compute_matrix() * camera.projection_matrix().inverse();
let world_pos = ndc_to_world.project_point3(ndc.extend(-1.0));
follower_position.0 = world_pos.truncate().adjust_precision();
if let Some(cursor_world_pos) = window
.cursor_position()
.and_then(|cursor| camera.viewport_to_world_2d(camera_transform, cursor))
{
follower_position.0 = cursor_world_pos.adjust_precision();
}
}
}
8 changes: 4 additions & 4 deletions crates/bevy_xpbd_2d/examples/many_shapes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::Y * 50.0 * 6.0),
Collider::cuboid(50.0 * 20.0, 50.0),
Collider::cuboid(50.0, 50.0),
));
// Floor
commands.spawn((
Expand All @@ -51,7 +51,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::NEG_Y * 50.0 * 6.0),
Collider::cuboid(50.0 * 20.0, 50.0),
Collider::cuboid(50.0, 50.0),
));
// Left wall
commands.spawn((
Expand All @@ -62,7 +62,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::NEG_X * 50.0 * 9.5),
Collider::cuboid(50.0, 50.0 * 11.0),
Collider::cuboid(50.0, 50.0),
));
// Right wall
commands.spawn((
Expand All @@ -73,7 +73,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::X * 50.0 * 9.5),
Collider::cuboid(50.0, 50.0 * 11.0),
Collider::cuboid(50.0, 50.0),
));

let ball = (
Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_xpbd_2d/examples/move_marbles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::Y * 50.0 * 6.0),
Collider::cuboid(50.0 * 20.0, 50.0),
Collider::cuboid(50.0, 50.0),
));
// Floor
commands.spawn((
Expand All @@ -51,7 +51,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::NEG_Y * 50.0 * 6.0),
Collider::cuboid(50.0 * 20.0, 50.0),
Collider::cuboid(50.0, 50.0),
));
// Left wall
commands.spawn((
Expand All @@ -62,7 +62,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::NEG_X * 50.0 * 9.5),
Collider::cuboid(50.0, 50.0 * 11.0),
Collider::cuboid(50.0, 50.0),
));
// Right wall
commands.spawn((
Expand All @@ -73,7 +73,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::X * 50.0 * 9.5),
Collider::cuboid(50.0, 50.0 * 11.0),
Collider::cuboid(50.0, 50.0),
));

let marble_radius = 5.0;
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_xpbd_2d/examples/one_way_platform_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::Y * 50.0 * 6.0),
Collider::cuboid(50.0 * 20.0, 50.0),
Collider::cuboid(50.0, 50.0),
));
// Floor
commands.spawn((
Expand All @@ -71,7 +71,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::NEG_Y * 50.0 * 6.0),
Collider::cuboid(50.0 * 20.0, 50.0),
Collider::cuboid(50.0, 50.0),
));
// Left wall
commands.spawn((
Expand All @@ -82,7 +82,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::NEG_X * 50.0 * 9.5),
Collider::cuboid(50.0, 50.0 * 11.0),
Collider::cuboid(50.0, 50.0),
));
// Right wall
commands.spawn((
Expand All @@ -93,7 +93,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::X * 50.0 * 9.5),
Collider::cuboid(50.0, 50.0 * 11.0),
Collider::cuboid(50.0, 50.0),
));

// For one-way platforms
Expand All @@ -113,7 +113,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::Y * 16.0 * 6.0 * y as Scalar),
Collider::cuboid(25.0 * 20.0, 25.0),
Collider::cuboid(50.0, 50.0),
OneWayPlatform::default(),
));
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_xpbd_3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ glam = { version = "0.24", features = ["approx"] }
derive_more = "0.99"
indexmap = "2.0.0"
fxhash = "0.2.1"
itertools = "0.11"

[dev-dependencies]
examples_common_3d = { path = "../examples_common_3d" }
benches_common_3d = { path = "../benches_common_3d" }
approx = "0.5"
criterion = { version = "0.4", features = ["html_reports"] }
insta = "1.0"
itertools = "0.10"

[[example]]
name = "basic_dynamic_character"
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_xpbd_3d/examples/cubes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn setup(
},
RigidBody::Static,
Position(Vector::NEG_Y * 2.0),
Collider::cuboid(100.0, 1.0, 100.0),
Collider::cuboid(1.0, 1.0, 1.0),
));

let cube_size = 2.0;
Expand All @@ -57,7 +57,7 @@ fn setup(
},
RigidBody::Dynamic,
Position(pos + Vector::Y * 5.0),
Collider::cuboid(cube_size, cube_size, cube_size),
Collider::cuboid(1.0, 1.0, 1.0),
Cube,
));
}
Expand Down
Loading

0 comments on commit 3bd7e0e

Please sign in to comment.