Skip to main content

Crate wde_physics

Crate wde_physics 

Source
Expand description

Provides physics world management, colliders, and raycasting functionalities using the Rapier physics engine.

§Features

  • Colliders: Add physics colliders to entities for collision detection (see Collider for supported shapes)
  • Raycasting: Cast rays through the physics world to detect intersections (see PhysicsWorld for raycasting methods)
  • Automatic Updates: Colliders automatically sync with entity transforms

§Creating Colliders

Attach a collider component to any entity with a transform:

commands.spawn((
    Transform::from_xyz(0.0, -1.0, 0.0),
    Collider::from(CuboidCollider::new(Vec3::new(10.0, 1.0, 10.0)).with_group(ColliderGroup::GROUP_1)),
));

This example creates a large flat collider representing the ground, assigned to GROUP_1. You can create various shapes (e.g., boxes, spheres, heightfields) and assign them to different groups for selective raycasting.

§Raycasting

Cast rays to detect physics intersections:

fn cast_ray_system(phworld: Res<PhysicsWorld>) {
    let ray = Ray::new(
        Vec3::new(0.0, 10.0, 0.0), // Origin above the ground
        Vec3::new(0.0, -1.0, 0.0), // Direction pointing downwards
    );

    // Cast the ray and check for hits
    // Use a filter to only hit colliders in GROUP_1
    if let Some((entity, toi)) = phworld.cast_ray(&ray, &RayCastConfig::with_filter(ColliderGroup::GROUP_1)) {
        let hit_point = ray.point_at(toi);
        println!("Hit entity {:?} at {:?}", entity, hit_point);
    }
}

§Camera-Based Raycasting

Cast rays from screen coordinates (useful for mouse picking):

fn mouse_picking(
    mut commands: Commands,
    phworld: Res<PhysicsWorld>,
    window: Single<&Window, With<PrimaryWindow>>,
    camera_query: Query<(&GlobalTransform, &CameraView), With<Camera>>,
) {
    // Get cursor position in NDC
    let Some(cursor_pos) = window.cursor_position() else { return };
    let cursor_ndc = cursor_pos / window.size();

    // Get camera data
    let Ok((camera_transform, camera_view)) = camera_query.get_single() else { return };
    let aspect_ratio = window.size().x / window.size().y;

    // Create ray from camera
    let ray = Ray::from_ndc(cursor_ndc, aspect_ratio, camera_transform, camera_view);

    // Cast the ray
    if let Some((entity, toi)) = phworld.cast_ray(&ray, &RayCastConfig::default()) {
        let hit_point = ray.point_at(toi);
        println!("Clicked on entity {:?} at {:?}", entity, hit_point);
    }
}

Structs§

PhysicsPlugin