add a SpatialBundle with visibility and transform components (#5344)
# Objective - Help user when they need to add both a `TransformBundle` and a `VisibilityBundle` ## Solution - Add a `SpatialBundle` adding all components
This commit is contained in:
parent
9c116d557d
commit
4affc8cd93
@ -22,16 +22,17 @@ use bevy_render::{
|
|||||||
skinning::{SkinnedMesh, SkinnedMeshInverseBindposes},
|
skinning::{SkinnedMesh, SkinnedMeshInverseBindposes},
|
||||||
Indices, Mesh, VertexAttributeValues,
|
Indices, Mesh, VertexAttributeValues,
|
||||||
},
|
},
|
||||||
|
prelude::SpatialBundle,
|
||||||
primitives::{Aabb, Frustum},
|
primitives::{Aabb, Frustum},
|
||||||
render_resource::{AddressMode, Face, FilterMode, PrimitiveTopology, SamplerDescriptor},
|
render_resource::{AddressMode, Face, FilterMode, PrimitiveTopology, SamplerDescriptor},
|
||||||
renderer::RenderDevice,
|
renderer::RenderDevice,
|
||||||
texture::{CompressedImageFormats, Image, ImageSampler, ImageType, TextureError},
|
texture::{CompressedImageFormats, Image, ImageSampler, ImageType, TextureError},
|
||||||
view::{VisibilityBundle, VisibleEntities},
|
view::VisibleEntities,
|
||||||
};
|
};
|
||||||
use bevy_scene::Scene;
|
use bevy_scene::Scene;
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use bevy_tasks::IoTaskPool;
|
use bevy_tasks::IoTaskPool;
|
||||||
use bevy_transform::{components::Transform, TransformBundle};
|
use bevy_transform::components::Transform;
|
||||||
|
|
||||||
use bevy_utils::{HashMap, HashSet};
|
use bevy_utils::{HashMap, HashSet};
|
||||||
use gltf::{
|
use gltf::{
|
||||||
@ -465,8 +466,7 @@ async fn load_gltf<'a, 'b>(
|
|||||||
|
|
||||||
world
|
world
|
||||||
.spawn()
|
.spawn()
|
||||||
.insert_bundle(TransformBundle::identity())
|
.insert_bundle(SpatialBundle::visible_identity())
|
||||||
.insert_bundle(VisibilityBundle::default())
|
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
for node in scene.nodes() {
|
for node in scene.nodes() {
|
||||||
let result = load_node(
|
let result = load_node(
|
||||||
@ -705,10 +705,9 @@ fn load_node(
|
|||||||
) -> Result<(), GltfError> {
|
) -> Result<(), GltfError> {
|
||||||
let transform = gltf_node.transform();
|
let transform = gltf_node.transform();
|
||||||
let mut gltf_error = None;
|
let mut gltf_error = None;
|
||||||
let mut node = world_builder.spawn_bundle(TransformBundle::from(Transform::from_matrix(
|
let mut node = world_builder.spawn_bundle(SpatialBundle::from(Transform::from_matrix(
|
||||||
Mat4::from_cols_array_2d(&transform.matrix()),
|
Mat4::from_cols_array_2d(&transform.matrix()),
|
||||||
)));
|
)));
|
||||||
node.insert_bundle(VisibilityBundle::default());
|
|
||||||
|
|
||||||
node.insert(node_name(gltf_node));
|
node.insert(node_name(gltf_node));
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ pub mod render_phase;
|
|||||||
pub mod render_resource;
|
pub mod render_resource;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
|
mod spatial_bundle;
|
||||||
pub mod texture;
|
pub mod texture;
|
||||||
pub mod view;
|
pub mod view;
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ pub mod prelude {
|
|||||||
color::Color,
|
color::Color,
|
||||||
mesh::{shape, Mesh},
|
mesh::{shape, Mesh},
|
||||||
render_resource::Shader,
|
render_resource::Shader,
|
||||||
|
spatial_bundle::SpatialBundle,
|
||||||
texture::Image,
|
texture::Image,
|
||||||
view::{ComputedVisibility, Msaa, Visibility, VisibilityBundle},
|
view::{ComputedVisibility, Msaa, Visibility, VisibilityBundle},
|
||||||
};
|
};
|
||||||
|
59
crates/bevy_render/src/spatial_bundle.rs
Normal file
59
crates/bevy_render/src/spatial_bundle.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
use bevy_ecs::prelude::Bundle;
|
||||||
|
use bevy_transform::prelude::{GlobalTransform, Transform};
|
||||||
|
|
||||||
|
use crate::view::{ComputedVisibility, Visibility};
|
||||||
|
|
||||||
|
/// A [`Bundle`] with the following [`Component`](bevy_ecs::component::Component)s:
|
||||||
|
/// * [`Visibility`] and [`ComputedVisibility`], which describe the visibility of an entity
|
||||||
|
/// * [`Transform`] and [`GlobalTransform`], which describe the position of an entity
|
||||||
|
///
|
||||||
|
/// * To show or hide an entity, you should set its [`Visibility`].
|
||||||
|
/// * To get the computed visibility of an entity, you should get its [`ComputedVisibility`].
|
||||||
|
/// * To place or move an entity, you should set its [`Transform`].
|
||||||
|
/// * To get the global transform of an entity, you should get its [`GlobalTransform`].
|
||||||
|
/// * For hierarchies to work correctly, you must have all four components.
|
||||||
|
/// * You may use the [`SpatialBundle`] to guarantee this.
|
||||||
|
#[derive(Bundle, Debug, Default)]
|
||||||
|
pub struct SpatialBundle {
|
||||||
|
/// The visibility of the entity.
|
||||||
|
pub visibility: Visibility,
|
||||||
|
/// The computed visibility of the entity.
|
||||||
|
pub computed: ComputedVisibility,
|
||||||
|
/// The transform of the entity.
|
||||||
|
pub transform: Transform,
|
||||||
|
/// The global transform of the entity.
|
||||||
|
pub global_transform: GlobalTransform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpatialBundle {
|
||||||
|
/// Creates a new [`SpatialBundle`] from a [`Transform`].
|
||||||
|
///
|
||||||
|
/// This initializes [`GlobalTransform`] as identity, and visibility as visible
|
||||||
|
#[inline]
|
||||||
|
pub const fn from_transform(transform: Transform) -> Self {
|
||||||
|
SpatialBundle {
|
||||||
|
transform,
|
||||||
|
// Note: `..Default::default()` cannot be used here, because it isn't const
|
||||||
|
..Self::visible_identity()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new identity [`SpatialBundle`], with no translation, rotation, and a scale of 1
|
||||||
|
/// on all axes.
|
||||||
|
#[inline]
|
||||||
|
pub const fn visible_identity() -> Self {
|
||||||
|
SpatialBundle {
|
||||||
|
transform: Transform::identity(),
|
||||||
|
global_transform: GlobalTransform::identity(),
|
||||||
|
visibility: Visibility::visible(),
|
||||||
|
computed: ComputedVisibility::not_visible(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Transform> for SpatialBundle {
|
||||||
|
#[inline]
|
||||||
|
fn from(transform: Transform) -> Self {
|
||||||
|
Self::from_transform(transform)
|
||||||
|
}
|
||||||
|
}
|
@ -34,19 +34,40 @@ pub struct Visibility {
|
|||||||
|
|
||||||
impl Default for Visibility {
|
impl Default for Visibility {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
Self::visible()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visibility {
|
||||||
|
/// Creates a new [`Visibility`], set as visible
|
||||||
|
pub const fn visible() -> Self {
|
||||||
Self { is_visible: true }
|
Self { is_visible: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering
|
/// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering
|
||||||
#[derive(Component, Clone, Reflect, Debug, Eq, PartialEq, Default)]
|
#[derive(Component, Clone, Reflect, Debug, Eq, PartialEq)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct ComputedVisibility {
|
pub struct ComputedVisibility {
|
||||||
is_visible_in_hierarchy: bool,
|
is_visible_in_hierarchy: bool,
|
||||||
is_visible_in_view: bool,
|
is_visible_in_view: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ComputedVisibility {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::not_visible()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ComputedVisibility {
|
impl ComputedVisibility {
|
||||||
|
/// Creates a new [`ComputedVisibility`], set as not visible
|
||||||
|
pub const fn not_visible() -> Self {
|
||||||
|
Self {
|
||||||
|
is_visible_in_hierarchy: false,
|
||||||
|
is_visible_in_view: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether this entity is visible to something this frame. This is true if and only if [`Self::is_visible_in_hierarchy`] and [`Self::is_visible_in_view`]
|
/// Whether this entity is visible to something this frame. This is true if and only if [`Self::is_visible_in_hierarchy`] and [`Self::is_visible_in_view`]
|
||||||
/// are true. This is the canonical method to call to determine if an entity should be drawn.
|
/// are true. This is the canonical method to call to determine if an entity should be drawn.
|
||||||
/// This value is updated in [`CoreStage::PostUpdate`] during the [`VisibilitySystems::CheckVisibility`] system label. Reading it from the
|
/// This value is updated in [`CoreStage::PostUpdate`] during the [`VisibilitySystems::CheckVisibility`] system label. Reading it from the
|
||||||
|
@ -8,7 +8,7 @@ use bevy_reflect::Reflect;
|
|||||||
/// Describe the position of an entity relative to the reference frame.
|
/// Describe the position of an entity relative to the reference frame.
|
||||||
///
|
///
|
||||||
/// * To place or move an entity, you should set its [`Transform`].
|
/// * To place or move an entity, you should set its [`Transform`].
|
||||||
/// * To get the global position of an entity, you should get its [`GlobalTransform`].
|
/// * To get the global transform of an entity, you should get its [`GlobalTransform`].
|
||||||
/// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
|
/// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
|
||||||
/// * You may use the [`TransformBundle`](crate::TransformBundle) to guarantee this.
|
/// * You may use the [`TransformBundle`](crate::TransformBundle) to guarantee this.
|
||||||
///
|
///
|
||||||
|
@ -9,7 +9,7 @@ use std::ops::Mul;
|
|||||||
/// to its parent position.
|
/// to its parent position.
|
||||||
///
|
///
|
||||||
/// * To place or move an entity, you should set its [`Transform`].
|
/// * To place or move an entity, you should set its [`Transform`].
|
||||||
/// * To get the global position of an entity, you should get its [`GlobalTransform`].
|
/// * To get the global transform of an entity, you should get its [`GlobalTransform`].
|
||||||
/// * To be displayed, an entity must have both a [`Transform`] and a [`GlobalTransform`].
|
/// * To be displayed, an entity must have both a [`Transform`] and a [`GlobalTransform`].
|
||||||
/// * You may use the [`TransformBundle`](crate::TransformBundle) to guarantee this.
|
/// * You may use the [`TransformBundle`](crate::TransformBundle) to guarantee this.
|
||||||
///
|
///
|
||||||
|
@ -20,7 +20,7 @@ use prelude::{GlobalTransform, Transform};
|
|||||||
/// [`Component`](bevy_ecs::component::Component)s, which describe the position of an entity.
|
/// [`Component`](bevy_ecs::component::Component)s, which describe the position of an entity.
|
||||||
///
|
///
|
||||||
/// * To place or move an entity, you should set its [`Transform`].
|
/// * To place or move an entity, you should set its [`Transform`].
|
||||||
/// * To get the global position of an entity, you should get its [`GlobalTransform`].
|
/// * To get the global transform of an entity, you should get its [`GlobalTransform`].
|
||||||
/// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
|
/// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
|
||||||
/// * You may use the [`TransformBundle`] to guarantee this.
|
/// * You may use the [`TransformBundle`] to guarantee this.
|
||||||
///
|
///
|
||||||
|
@ -125,8 +125,7 @@ fn setup(
|
|||||||
.insert_bundle((planet, player))
|
.insert_bundle((planet, player))
|
||||||
.with_children(|p| {
|
.with_children(|p| {
|
||||||
// This entity is just used for animation, but doesn't display anything
|
// This entity is just used for animation, but doesn't display anything
|
||||||
p.spawn_bundle(TransformBundle::default())
|
p.spawn_bundle(SpatialBundle::default())
|
||||||
.insert_bundle(VisibilityBundle::default())
|
|
||||||
// Add the Name component
|
// Add the Name component
|
||||||
.insert(orbit_controller)
|
.insert(orbit_controller)
|
||||||
.with_children(|p| {
|
.with_children(|p| {
|
||||||
|
Loading…
Reference in New Issue
Block a user