Skip to content

Add Transform2d component #8268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions crates/bevy_core_pipeline/src/core_2d/camera_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ use crate::{
tonemapping::{DebandDither, Tonemapping},
};
use bevy_ecs::prelude::*;
use bevy_math::Vec3;
use bevy_reflect::Reflect;
use bevy_render::{
camera::{Camera, CameraProjection, CameraRenderGraph, OrthographicProjection},
extract_component::ExtractComponent,
primitives::Frustum,
view::VisibleEntities,
};
use bevy_transform::prelude::{GlobalTransform, Transform};
use bevy_transform::components::{GlobalTransform2d, Transform2d};

#[derive(Component, Default, Reflect, Clone, ExtractComponent)]
#[extract_component_filter(With<Camera>)]
Expand All @@ -26,8 +27,8 @@ pub struct Camera2dBundle {
pub projection: OrthographicProjection,
pub visible_entities: VisibleEntities,
pub frustum: Frustum,
pub transform: Transform,
pub global_transform: GlobalTransform,
pub transform: Transform2d,
pub global_transform: GlobalTransform2d,
pub camera_2d: Camera2d,
pub tonemapping: Tonemapping,
pub deband_dither: DebandDither,
Expand All @@ -40,21 +41,18 @@ impl Default for Camera2dBundle {
near: -1000.,
..Default::default()
};
let transform = Transform::default();
let view_projection =
projection.get_projection_matrix() * transform.compute_matrix().inverse();
let frustum = Frustum::from_view_projection_custom_far(
&view_projection,
&transform.translation,
&transform.back(),
&projection.get_projection_matrix(),
&Vec3::ZERO,
&Vec3::Z,
projection.far(),
);
Self {
camera_render_graph: CameraRenderGraph::new(crate::core_2d::graph::NAME),
projection,
visible_entities: VisibleEntities::default(),
frustum,
transform,
transform: Default::default(),
global_transform: Default::default(),
camera: Camera::default(),
camera_2d: Camera2d::default(),
Expand All @@ -78,14 +76,16 @@ impl Camera2dBundle {
far,
..Default::default()
};
let transform = Transform::from_xyz(0.0, 0.0, far - 0.1);
let view_projection =
projection.get_projection_matrix() * transform.compute_matrix().inverse();
let transform = Transform2d::from_xyz(0.0, 0.0, far - 0.1);
let view_projection = projection.get_projection_matrix()
* GlobalTransform2d::from(transform)
.compute_matrix()
.inverse();
let frustum = Frustum::from_view_projection_custom_far(
&view_projection,
&transform.translation,
&transform.back(),
projection.far(),
&transform.translation.extend(transform.z_translation),
&Vec3::Z,
far,
);
Self {
camera_render_graph: CameraRenderGraph::new(crate::core_2d::graph::NAME),
Expand Down
11 changes: 6 additions & 5 deletions crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use bevy_ecs::{
use bevy_log::warn;
use bevy_math::{vec2, Mat4, Ray, Rect, URect, UVec2, UVec4, Vec2, Vec3};
use bevy_reflect::prelude::*;
use bevy_transform::components::GlobalTransform;
use bevy_transform::components::{AnyGlobalTransform, GlobalTransform, GlobalTransform2d};
use bevy_utils::{HashMap, HashSet};
use bevy_window::{
NormalizedWindowRef, PrimaryWindow, Window, WindowCreated, WindowRef, WindowResized,
Expand Down Expand Up @@ -300,15 +300,16 @@ impl Camera {
/// May panic. See [`ndc_to_world`](Camera::ndc_to_world).
pub fn viewport_to_world_2d(
&self,
camera_transform: &GlobalTransform,
camera_transform: &GlobalTransform2d,
mut viewport_position: Vec2,
) -> Option<Vec2> {
let target_size = self.logical_viewport_size()?;
// Flip the Y co-ordinate origin from the top to the bottom.
viewport_position.y = target_size.y - viewport_position.y;
let ndc = viewport_position * 2. / target_size - Vec2::ONE;

let world_near_plane = self.ndc_to_world(camera_transform, ndc.extend(1.))?;
let world_near_plane =
self.ndc_to_world(&GlobalTransform::from(*camera_transform), ndc.extend(1.))?;

Some(world_near_plane.truncate())
}
Expand Down Expand Up @@ -639,7 +640,7 @@ pub fn extract_cameras(
Entity,
&Camera,
&CameraRenderGraph,
&GlobalTransform,
AnyGlobalTransform,
&VisibleEntities,
Option<&ColorGrading>,
Option<&TemporalJitter>,
Expand Down Expand Up @@ -699,7 +700,7 @@ pub fn extract_cameras(
},
ExtractedView {
projection: camera.projection_matrix(),
transform: *transform,
transform: transform.get(),
view_projection: None,
hdr: camera.hdr,
viewport: UVec4::new(
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub mod prelude {
color::Color,
mesh::{morph::MorphWeights, shape, Mesh},
render_resource::Shader,
spatial_bundle::SpatialBundle,
spatial_bundle::{Spatial2dBundle, SpatialBundle},
texture::{Image, ImagePlugin},
view::{InheritedVisibility, Msaa, ViewVisibility, Visibility, VisibilityBundle},
ExtractSchedule,
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_render/src/primitives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,14 @@ impl HalfSpace {
/// The frustum component is typically added from a bundle, either the `Camera2dBundle`
/// or the `Camera3dBundle`.
/// It is usually updated automatically by [`update_frusta`] from the
/// [`CameraProjection`] component and [`GlobalTransform`] of the camera entity.
/// [`CameraProjection`] component and the [`GlobalTransform`] or [`GlobalTransform2d`] of the camera entity.
///
/// [`Camera`]: crate::camera::Camera
/// [`NoFrustumCulling`]: crate::view::visibility::NoFrustumCulling
/// [`update_frusta`]: crate::view::visibility::update_frusta
/// [`CameraProjection`]: crate::camera::CameraProjection
/// [`GlobalTransform`]: bevy_transform::components::GlobalTransform
/// [`GlobalTransform2d`]: bevy_transform::components::GlobalTransform2d
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
#[reflect(Component)]
pub struct Frustum {
Expand Down
65 changes: 63 additions & 2 deletions crates/bevy_render/src/spatial_bundle.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use bevy_ecs::prelude::Bundle;
use bevy_transform::prelude::{GlobalTransform, Transform};
use bevy_transform::prelude::{GlobalTransform, GlobalTransform2d, Transform, Transform2d};

use crate::view::{InheritedVisibility, ViewVisibility, Visibility};

/// A [`Bundle`] that allows the correct positional rendering of an entity.
/// A [`Bundle`] that allows the correct positional rendering of an entity in 3D.
///
/// It consists of transform components,
/// controlling position, rotation and scale of the entity,
Expand Down Expand Up @@ -63,3 +63,64 @@ impl From<Transform> for SpatialBundle {
Self::from_transform(transform)
}
}

/// A [`Bundle`] that allows the correct positional rendering of an entity in 2D.
///
/// It consists of transform components,
/// controlling position, rotation and scale of the entity,
/// but also visibility components,
/// which determine whether the entity is visible or not.
///
/// Parent-child hierarchies of entities must contain
/// all the [`Component`]s in this `Bundle`
/// to be rendered correctly.
///
/// [`Component`]: bevy_ecs::component::Component
#[derive(Bundle, Debug, Default)]
pub struct Spatial2dBundle {
/// The visibility of the entity.
pub visibility: Visibility,
/// The inherited visibility of the entity.
pub inherited_visibility: InheritedVisibility,
/// The view visibility of the entity.
pub view_visibility: ViewVisibility,
/// The transform of the entity.
pub transform: Transform2d,
/// The global transform of the entity.
pub global_transform: GlobalTransform2d,
}

impl Spatial2dBundle {
/// Creates a new [`Spatial2dBundle`] from a [`Transform`].
///
/// This initializes [`GlobalTransform`] as identity, and visibility as visible
#[inline]
pub const fn from_transform(transform: Transform2d) -> Self {
Spatial2dBundle {
transform,
..Self::INHERITED_IDENTITY
}
}

/// A visible [`Spatial2dBundle`], with no translation, rotation, and a scale of 1 on all axes.
pub const INHERITED_IDENTITY: Self = Spatial2dBundle {
visibility: Visibility::Inherited,
inherited_visibility: InheritedVisibility::HIDDEN,
view_visibility: ViewVisibility::HIDDEN,
transform: Transform2d::IDENTITY,
global_transform: GlobalTransform2d::IDENTITY,
};

/// An invisible [`Spatial2dBundle`], with no translation, rotation, and a scale of 1 on all axes.
pub const HIDDEN_IDENTITY: Self = Spatial2dBundle {
visibility: Visibility::Hidden,
..Self::INHERITED_IDENTITY
};
}

impl From<Transform2d> for Spatial2dBundle {
#[inline]
fn from(transform: Transform2d) -> Self {
Self::from_transform(transform)
}
}
19 changes: 14 additions & 5 deletions crates/bevy_render/src/view/visibility/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use bevy_asset::{Assets, Handle};
use bevy_ecs::prelude::*;
use bevy_hierarchy::{Children, Parent};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_transform::{components::GlobalTransform, TransformSystem};
use bevy_transform::{
components::{AnyGlobalTransform, GlobalTransform, GlobalTransform2d},
TransformSystem,
};
use std::cell::Cell;
use thread_local::ThreadLocal;

Expand Down Expand Up @@ -280,13 +283,18 @@ pub fn calculate_bounds(
/// This system is used in system sets [`VisibilitySystems::UpdateProjectionFrusta`],
/// [`VisibilitySystems::UpdatePerspectiveFrusta`], and
/// [`VisibilitySystems::UpdateOrthographicFrusta`].
pub fn update_frusta<T: Component + CameraProjection + Send + Sync + 'static>(
pub fn update_frusta<T: Component + CameraProjection>(
mut views: Query<
(&GlobalTransform, &T, &mut Frustum),
Or<(Changed<GlobalTransform>, Changed<T>)>,
(AnyGlobalTransform, &T, &mut Frustum),
Or<(
Changed<GlobalTransform>,
Changed<GlobalTransform2d>,
Changed<T>,
)>,
>,
) {
for (transform, projection, mut frustum) in &mut views {
let transform = transform.get();
let view_projection =
projection.get_projection_matrix() * transform.compute_matrix().inverse();
*frustum = Frustum::from_view_projection_custom_far(
Expand Down Expand Up @@ -391,7 +399,7 @@ pub fn check_visibility(
&mut ViewVisibility,
Option<&RenderLayers>,
&Aabb,
&GlobalTransform,
AnyGlobalTransform,
Has<NoFrustumCulling>,
)>,
mut visible_no_aabb_query: Query<
Expand Down Expand Up @@ -432,6 +440,7 @@ pub fn check_visibility(

// If we have an aabb and transform, do frustum culling
if !no_frustum_culling {
let transform = transform.get();
let model = transform.affine();
let model_sphere = Sphere {
center: model.transform_point3a(model_aabb.center),
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_sprite/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use bevy_render::{
texture::Image,
view::{InheritedVisibility, ViewVisibility, Visibility},
};
use bevy_transform::components::{GlobalTransform, Transform};
use bevy_transform::components::{GlobalTransform2d, Transform2d};

#[derive(Bundle, Clone, Default)]
pub struct SpriteBundle {
pub sprite: Sprite,
pub transform: Transform,
pub global_transform: GlobalTransform,
pub transform: Transform2d,
pub global_transform: GlobalTransform2d,
pub texture: Handle<Image>,
/// User indication of whether an entity is visible
pub visibility: Visibility,
Expand All @@ -33,8 +33,8 @@ pub struct SpriteSheetBundle {
/// A handle to the texture atlas that holds the sprite images
pub texture_atlas: Handle<TextureAtlas>,
/// Data pertaining to how the sprite is drawn on the screen
pub transform: Transform,
pub global_transform: GlobalTransform,
pub transform: Transform2d,
pub global_transform: GlobalTransform2d,
/// User indication of whether an entity is visible
pub visibility: Visibility,
pub inherited_visibility: InheritedVisibility,
Expand Down
18 changes: 9 additions & 9 deletions crates/bevy_sprite/src/collide_aabb.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Utilities for detecting if and on which side two axis-aligned bounding boxes (AABB) collide.

use bevy_math::{Vec2, Vec3};
use bevy_math::Vec2;

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Collision {
Expand All @@ -14,19 +14,19 @@ pub enum Collision {
// TODO: ideally we can remove this once bevy gets a physics system
/// Axis-aligned bounding box collision with "side" detection
/// * `a_pos` and `b_pos` are the center positions of the rectangles, typically obtained by
/// extracting the `translation` field from a [`Transform`](bevy_transform::components::Transform) component
/// extracting the `translation` field from a [`Transform2d`](bevy_transform::components::Transform2d) component
/// * `a_size` and `b_size` are the dimensions (width and height) of the rectangles.
///
/// The return value is the side of `B` that `A` has collided with. [`Collision::Left`] means that
/// `A` collided with `B`'s left side. [`Collision::Top`] means that `A` collided with `B`'s top side.
/// If the collision occurs on multiple sides, the side with the shallowest penetration is returned.
/// If all sides are involved, [`Collision::Inside`] is returned.
pub fn collide(a_pos: Vec3, a_size: Vec2, b_pos: Vec3, b_size: Vec2) -> Option<Collision> {
let a_min = a_pos.truncate() - a_size / 2.0;
let a_max = a_pos.truncate() + a_size / 2.0;
pub fn collide(a_pos: Vec2, a_size: Vec2, b_pos: Vec2, b_size: Vec2) -> Option<Collision> {
let a_min = a_pos - a_size / 2.0;
let a_max = a_pos + a_size / 2.0;

let b_min = b_pos.truncate() - b_size / 2.0;
let b_max = b_pos.truncate() + b_size / 2.0;
let b_min = b_pos - b_size / 2.0;
let b_max = b_pos + b_size / 2.0;

// check to see if the two rectangles are intersecting
if a_min.x < b_max.x && a_max.x > b_min.x && a_min.y < b_max.y && a_max.y > b_min.y {
Expand Down Expand Up @@ -71,9 +71,9 @@ mod test {
b: (f32, f32, f32, f32),
) -> Option<Collision> {
collide(
Vec3::new(a.0, a.1, 0.),
Vec2::new(a.0, a.1),
Vec2::new(a.2, a.3),
Vec3::new(b.0, b.1, 0.),
Vec2::new(b.0, b.1),
Vec2::new(b.2, b.3),
)
}
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_sprite/src/mesh2d/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use bevy_render::{
view::{ExtractedView, InheritedVisibility, Msaa, ViewVisibility, Visibility, VisibleEntities},
Extract, ExtractSchedule, Render, RenderApp, RenderSet,
};
use bevy_transform::components::{GlobalTransform, Transform};
use bevy_transform::components::{GlobalTransform2d, Transform2d};
use bevy_utils::{EntityHashMap, FloatOrd, HashMap, HashSet};
use std::hash::Hash;
use std::marker::PhantomData;
Expand Down Expand Up @@ -625,8 +625,8 @@ fn prepare_material2d<M: Material2d>(
pub struct MaterialMesh2dBundle<M: Material2d> {
pub mesh: Mesh2dHandle,
pub material: Handle<M>,
pub transform: Transform,
pub global_transform: GlobalTransform,
pub transform: Transform2d,
pub global_transform: GlobalTransform2d,
/// User indication of whether an entity is visible
pub visibility: Visibility,
// Inherited visibility of an entity.
Expand Down
Loading