Struct bevy::math::bounding::Aabb2d

pub struct Aabb2d {
    pub min: Vec2,
    pub max: Vec2,
}
Expand description

A 2D axis-aligned bounding box, or bounding rectangle

Fields§

§min: Vec2

The minimum, conventionally bottom-left, point of the box

§max: Vec2

The maximum, conventionally top-right, point of the box

Implementations§

§

impl Aabb2d

pub fn new(center: Vec2, half_size: Vec2) -> Aabb2d

Constructs an AABB from its center and half-size.

Examples found in repository?
examples/2d/bounding_2d.rs (line 348)
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
fn aabb_cast_system(
    mut gizmos: Gizmos,
    time: Res<Time>,
    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
) {
    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
    let aabb_cast = AabbCast2d {
        aabb: Aabb2d::new(Vec2::ZERO, Vec2::splat(15.)),
        ray: ray_cast,
    };

    for (volume, mut intersects) in volumes.iter_mut() {
        let toi = match *volume {
            CurrentVolume::Aabb(a) => aabb_cast.aabb_collision_at(a),
            CurrentVolume::Circle(_) => None,
        };

        **intersects = toi.is_some();
        if let Some(toi) = toi {
            gizmos.rect_2d(
                aabb_cast.ray.ray.origin
                    + *aabb_cast.ray.ray.direction * toi
                    + aabb_cast.aabb.center(),
                0.,
                aabb_cast.aabb.half_size() * 2.,
                Color::GREEN,
            );
        }
    }
}

fn bounding_circle_cast_system(
    mut gizmos: Gizmos,
    time: Res<Time>,
    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
) {
    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
    let circle_cast = BoundingCircleCast {
        circle: BoundingCircle::new(Vec2::ZERO, 15.),
        ray: ray_cast,
    };

    for (volume, mut intersects) in volumes.iter_mut() {
        let toi = match *volume {
            CurrentVolume::Aabb(_) => None,
            CurrentVolume::Circle(c) => circle_cast.circle_collision_at(c),
        };

        **intersects = toi.is_some();
        if let Some(toi) = toi {
            gizmos.circle_2d(
                circle_cast.ray.ray.origin
                    + *circle_cast.ray.ray.direction * toi
                    + circle_cast.circle.center(),
                circle_cast.circle.radius(),
                Color::GREEN,
            );
        }
    }
}

fn get_intersection_position(time: &Time) -> Vec2 {
    let x = (0.8 * time.elapsed_seconds()).cos() * 250.;
    let y = (0.4 * time.elapsed_seconds()).sin() * 100.;
    Vec2::new(x, y)
}

fn aabb_intersection_system(
    mut gizmos: Gizmos,
    time: Res<Time>,
    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
) {
    let center = get_intersection_position(&time);
    let aabb = Aabb2d::new(center, Vec2::splat(50.));
    gizmos.rect_2d(center, 0., aabb.half_size() * 2., Color::YELLOW);

    for (volume, mut intersects) in volumes.iter_mut() {
        let hit = match volume {
            CurrentVolume::Aabb(a) => aabb.intersects(a),
            CurrentVolume::Circle(c) => aabb.intersects(c),
        };

        **intersects = hit;
    }
}
More examples
Hide additional examples
examples/games/breakout.rs (lines 371-374)
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
fn check_for_collisions(
    mut commands: Commands,
    mut scoreboard: ResMut<Scoreboard>,
    mut ball_query: Query<(&mut Velocity, &Transform), With<Ball>>,
    collider_query: Query<(Entity, &Transform, Option<&Brick>), With<Collider>>,
    mut collision_events: EventWriter<CollisionEvent>,
) {
    let (mut ball_velocity, ball_transform) = ball_query.single_mut();

    // check collision with walls
    for (collider_entity, transform, maybe_brick) in &collider_query {
        let collision = collide_with_side(
            BoundingCircle::new(ball_transform.translation.truncate(), BALL_DIAMETER / 2.),
            Aabb2d::new(
                transform.translation.truncate(),
                transform.scale.truncate() / 2.,
            ),
        );

        if let Some(collision) = collision {
            // Sends a collision event so that other systems can react to the collision
            collision_events.send_default();

            // Bricks should be despawned and increment the scoreboard on collision
            if maybe_brick.is_some() {
                scoreboard.score += 1;
                commands.entity(collider_entity).despawn();
            }

            // reflect the ball when it collides
            let mut reflect_x = false;
            let mut reflect_y = false;

            // only reflect if the ball's velocity is going in the opposite direction of the
            // collision
            match collision {
                Collision::Left => reflect_x = ball_velocity.x > 0.0,
                Collision::Right => reflect_x = ball_velocity.x < 0.0,
                Collision::Top => reflect_y = ball_velocity.y < 0.0,
                Collision::Bottom => reflect_y = ball_velocity.y > 0.0,
            }

            // reflect velocity on the x-axis if we hit something on the x-axis
            if reflect_x {
                ball_velocity.x = -ball_velocity.x;
            }

            // reflect velocity on the y-axis if we hit something on the y-axis
            if reflect_y {
                ball_velocity.y = -ball_velocity.y;
            }
        }
    }
}

pub fn from_point_cloud( translation: Vec2, rotation: f32, points: &[Vec2] ) -> Aabb2d

Computes the smallest Aabb2d containing the given set of points, transformed by translation and rotation.

§Panics

Panics if the given set of points is empty.

pub fn bounding_circle(&self) -> BoundingCircle

Computes the smallest BoundingCircle containing this Aabb2d.

pub fn closest_point(&self, point: Vec2) -> Vec2

Finds the point on the AABB that is closest to the given point.

If the point is outside the AABB, the returned point will be on the perimeter of the AABB. Otherwise, it will be inside the AABB and returned as is.

Examples found in repository?
examples/games/breakout.rs (line 445)
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
fn collide_with_side(ball: BoundingCircle, wall: Aabb2d) -> Option<Collision> {
    if !ball.intersects(&wall) {
        return None;
    }

    let closest = wall.closest_point(ball.center());
    let offset = ball.center() - closest;
    let side = if offset.x.abs() > offset.y.abs() {
        if offset.x < 0. {
            Collision::Left
        } else {
            Collision::Right
        }
    } else if offset.y > 0. {
        Collision::Top
    } else {
        Collision::Bottom
    };

    Some(side)
}

Trait Implementations§

§

impl BoundingVolume for Aabb2d

§

type Position = Vec2

The position type used for the volume. This should be Vec2 for 2D and Vec3 for 3D.
§

type HalfSize = Vec2

The type used for the size of the bounding volume. Usually a half size. For example an f32 radius for a circle, or a Vec3 with half sizes for x, y and z for a 3D axis-aligned bounding box
§

fn center(&self) -> <Aabb2d as BoundingVolume>::Position

Returns the center of the bounding volume.
§

fn half_size(&self) -> <Aabb2d as BoundingVolume>::HalfSize

Returns the half size of the bounding volume.
§

fn visible_area(&self) -> f32

Computes the visible surface area of the bounding volume. This method can be useful to make decisions about merging bounding volumes, using a Surface Area Heuristic. Read more
§

fn contains(&self, other: &Aabb2d) -> bool

Checks if this bounding volume contains another one.
§

fn merge(&self, other: &Aabb2d) -> Aabb2d

Computes the smallest bounding volume that contains both self and other.
§

fn grow(&self, amount: <Aabb2d as BoundingVolume>::HalfSize) -> Aabb2d

Increase the size of the bounding volume in each direction by the given amount
§

fn shrink(&self, amount: <Aabb2d as BoundingVolume>::HalfSize) -> Aabb2d

Decrease the size of the bounding volume in each direction by the given amount
§

impl Clone for Aabb2d

§

fn clone(&self) -> Aabb2d

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Aabb2d

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl IntersectsVolume<Aabb2d> for Aabb2d

§

fn intersects(&self, other: &Aabb2d) -> bool

Check if a volume intersects with this intersection test
§

impl IntersectsVolume<Aabb2d> for AabbCast2d

§

fn intersects(&self, volume: &Aabb2d) -> bool

Check if a volume intersects with this intersection test
§

impl IntersectsVolume<Aabb2d> for BoundingCircle

§

fn intersects(&self, aabb: &Aabb2d) -> bool

Check if a volume intersects with this intersection test
§

impl IntersectsVolume<Aabb2d> for RayCast2d

§

fn intersects(&self, volume: &Aabb2d) -> bool

Check if a volume intersects with this intersection test
§

impl IntersectsVolume<BoundingCircle> for Aabb2d

§

fn intersects(&self, circle: &BoundingCircle) -> bool

Check if a volume intersects with this intersection test
§

impl Copy for Aabb2d

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<Image>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

§

fn clone_type_data(&self) -> Box<dyn TypeData>

§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> Settings for T
where T: 'static + Send + Sync,

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,