Merge branch 'main' into transmission

This commit is contained in:
Marco Buono 2023-10-18 23:55:40 -03:00
commit af291b1ca2
12 changed files with 218 additions and 17 deletions

View File

@ -71,7 +71,11 @@ bevy_asset = ["bevy_internal/bevy_asset"]
bevy_audio = ["bevy_internal/bevy_audio"] bevy_audio = ["bevy_internal/bevy_audio"]
# Provides cameras and other basic render pipeline features # Provides cameras and other basic render pipeline features
bevy_core_pipeline = ["bevy_internal/bevy_core_pipeline", "bevy_asset", "bevy_render"] bevy_core_pipeline = [
"bevy_internal/bevy_core_pipeline",
"bevy_asset",
"bevy_render",
]
# Plugin for dynamic loading (using [libloading](https://crates.io/crates/libloading)) # Plugin for dynamic loading (using [libloading](https://crates.io/crates/libloading))
bevy_dynamic_plugin = ["bevy_internal/bevy_dynamic_plugin"] bevy_dynamic_plugin = ["bevy_internal/bevy_dynamic_plugin"]
@ -83,7 +87,12 @@ bevy_gilrs = ["bevy_internal/bevy_gilrs"]
bevy_gltf = ["bevy_internal/bevy_gltf", "bevy_asset", "bevy_scene", "bevy_pbr"] bevy_gltf = ["bevy_internal/bevy_gltf", "bevy_asset", "bevy_scene", "bevy_pbr"]
# Adds PBR rendering # Adds PBR rendering
bevy_pbr = ["bevy_internal/bevy_pbr", "bevy_asset", "bevy_render", "bevy_core_pipeline"] bevy_pbr = [
"bevy_internal/bevy_pbr",
"bevy_asset",
"bevy_render",
"bevy_core_pipeline",
]
# Provides rendering functionality # Provides rendering functionality
bevy_render = ["bevy_internal/bevy_render"] bevy_render = ["bevy_internal/bevy_render"]
@ -98,7 +107,12 @@ bevy_sprite = ["bevy_internal/bevy_sprite", "bevy_render", "bevy_core_pipeline"]
bevy_text = ["bevy_internal/bevy_text", "bevy_asset", "bevy_sprite"] bevy_text = ["bevy_internal/bevy_text", "bevy_asset", "bevy_sprite"]
# A custom ECS-driven UI framework # A custom ECS-driven UI framework
bevy_ui = ["bevy_internal/bevy_ui", "bevy_core_pipeline", "bevy_text", "bevy_sprite"] bevy_ui = [
"bevy_internal/bevy_ui",
"bevy_core_pipeline",
"bevy_text",
"bevy_sprite",
]
# winit window and input backend # winit window and input backend
bevy_winit = ["bevy_internal/bevy_winit"] bevy_winit = ["bevy_internal/bevy_winit"]
@ -113,7 +127,11 @@ trace_chrome = ["trace", "bevy_internal/trace_chrome"]
trace_tracy = ["trace", "bevy_internal/trace_tracy"] trace_tracy = ["trace", "bevy_internal/trace_tracy"]
# Tracing support, with memory profiling, exposing a port for Tracy # Tracing support, with memory profiling, exposing a port for Tracy
trace_tracy_memory = ["trace", "bevy_internal/trace_tracy", "bevy_internal/trace_tracy_memory"] trace_tracy_memory = [
"trace",
"bevy_internal/trace_tracy",
"bevy_internal/trace_tracy_memory",
]
# Tracing support # Tracing support
trace = ["bevy_internal/trace"] trace = ["bevy_internal/trace"]
@ -244,7 +262,7 @@ shader_format_spirv = ["bevy_internal/shader_format_spirv"]
# Enable support for transmission-related textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs # Enable support for transmission-related textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs
pbr_transmission_textures = ["bevy_internal/pbr_transmission_textures"] pbr_transmission_textures = ["bevy_internal/pbr_transmission_textures"]
# Enable some limitations to be able to use WebGL2. If not enabled, it will default to WebGPU in Wasm # Enable some limitations to be able to use WebGL2. If not enabled, it will default to WebGPU in Wasm. Please refer to the [WebGL2 and WebGPU](https://github.com/bevyengine/bevy/tree/latest/examples#webgl2-and-webgpu) section of the examples README for more information on how to run Wasm builds with WebGPU.
webgl2 = ["bevy_internal/webgl"] webgl2 = ["bevy_internal/webgl"]
# Enables watching the filesystem for Bevy Asset hot-reloading # Enables watching the filesystem for Bevy Asset hot-reloading

View File

@ -48,8 +48,11 @@ Before contributing or participating in discussions with the community, you shou
* **[GitHub Discussions](https://github.com/bevyengine/bevy/discussions):** The best place for questions about Bevy, answered right here! * **[GitHub Discussions](https://github.com/bevyengine/bevy/discussions):** The best place for questions about Bevy, answered right here!
* **[Bevy Assets](https://bevyengine.org/assets/):** A collection of awesome Bevy projects, tools, plugins and learning materials. * **[Bevy Assets](https://bevyengine.org/assets/):** A collection of awesome Bevy projects, tools, plugins and learning materials.
### Contributing
If you'd like to help build Bevy, check out the **[Contributor's Guide](https://github.com/bevyengine/bevy/blob/main/CONTRIBUTING.md)**. If you'd like to help build Bevy, check out the **[Contributor's Guide](https://github.com/bevyengine/bevy/blob/main/CONTRIBUTING.md)**.
For simple problems, feel free to open an issue or PR and tackle it yourself! For simple problems, feel free to [open an issue](https://github.com/bevyengine/bevy/issues) or
[PR](https://github.com/bevyengine/bevy/pulls) and tackle it yourself!
For more complex architecture decisions and experimental mad science, please open an [RFC](https://github.com/bevyengine/rfcs) (Request For Comments) so we can brainstorm together effectively! For more complex architecture decisions and experimental mad science, please open an [RFC](https://github.com/bevyengine/rfcs) (Request For Comments) so we can brainstorm together effectively!

View File

@ -288,6 +288,14 @@ impl App {
panic!("App::run() was called from within Plugin::build(), which is not allowed."); panic!("App::run() was called from within Plugin::build(), which is not allowed.");
} }
if app.ready() {
// If we're already ready, we finish up now and advance one frame.
// This prevents black frames during the launch transition on iOS.
app.finish();
app.cleanup();
app.update();
}
let runner = std::mem::replace(&mut app.runner, Box::new(run_once)); let runner = std::mem::replace(&mut app.runner, Box::new(run_once));
(runner)(app); (runner)(app);
} }
@ -861,7 +869,7 @@ impl App {
} }
/// When doing [ambiguity checking](bevy_ecs::schedule::ScheduleBuildSettings) this /// When doing [ambiguity checking](bevy_ecs::schedule::ScheduleBuildSettings) this
/// ignores systems that are ambiguious on [`Component`] T. /// ignores systems that are ambiguous on [`Component`] T.
/// ///
/// This settings only applies to the main world. To apply this to other worlds call the /// This settings only applies to the main world. To apply this to other worlds call the
/// [corresponding method](World::allow_ambiguous_component) on World /// [corresponding method](World::allow_ambiguous_component) on World
@ -899,7 +907,7 @@ impl App {
} }
/// When doing [ambiguity checking](bevy_ecs::schedule::ScheduleBuildSettings) this /// When doing [ambiguity checking](bevy_ecs::schedule::ScheduleBuildSettings) this
/// ignores systems that are ambiguious on [`Resource`] T. /// ignores systems that are ambiguous on [`Resource`] T.
/// ///
/// This settings only applies to the main world. To apply this to other worlds call the /// This settings only applies to the main world. To apply this to other worlds call the
/// [corresponding method](World::allow_ambiguous_resource) on World /// [corresponding method](World::allow_ambiguous_resource) on World

View File

@ -71,12 +71,14 @@ impl Plugin for ScheduleRunnerPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
let run_mode = self.run_mode; let run_mode = self.run_mode;
app.set_runner(move |mut app: App| { app.set_runner(move |mut app: App| {
while !app.ready() { if !app.ready() {
#[cfg(not(target_arch = "wasm32"))] while !app.ready() {
bevy_tasks::tick_global_task_pools_on_main_thread(); #[cfg(not(target_arch = "wasm32"))]
bevy_tasks::tick_global_task_pools_on_main_thread();
}
app.finish();
app.cleanup();
} }
app.finish();
app.cleanup();
let mut app_exit_event_reader = ManualEventReader::<AppExit>::default(); let mut app_exit_event_reader = ManualEventReader::<AppExit>::default();
match run_mode { match run_mode {

View File

@ -19,6 +19,8 @@ serde = { version = "1", features = ["derive"], optional = true }
[dev-dependencies] [dev-dependencies]
bevy_tasks = { path = "../bevy_tasks", version = "0.12.0-dev" } bevy_tasks = { path = "../bevy_tasks", version = "0.12.0-dev" }
approx = "0.5.1"
glam = { version = "0.24", features = ["approx"] }
[features] [features]
serialize = ["dep:serde", "bevy_math/serialize"] serialize = ["dep:serde", "bevy_math/serialize"]

View File

@ -420,6 +420,15 @@ impl Mul<Transform> for Transform {
} }
} }
impl Mul<GlobalTransform> for Transform {
type Output = GlobalTransform;
#[inline]
fn mul(self, global_transform: GlobalTransform) -> Self::Output {
GlobalTransform::from(self) * global_transform
}
}
impl Mul<Vec3> for Transform { impl Mul<Vec3> for Transform {
type Output = Vec3; type Output = Vec3;

View File

@ -0,0 +1,142 @@
//! System parameter for computing up-to-date [`GlobalTransform`]s.
use bevy_ecs::{
prelude::Entity,
query::QueryEntityError,
system::{Query, SystemParam},
};
use bevy_hierarchy::{HierarchyQueryExt, Parent};
use crate::components::{GlobalTransform, Transform};
/// System parameter for computing up-to-date [`GlobalTransform`]s.
///
/// Computing an entity's [`GlobalTransform`] can be expensive so it is recommended
/// you use the [`GlobalTransform`] component stored on the entity, unless you need
/// a [`GlobalTransform`] that reflects the changes made to any [`Transform`]s since
/// the last time the transform propagation systems ran.
#[derive(SystemParam)]
pub struct TransformHelper<'w, 's> {
parent_query: Query<'w, 's, &'static Parent>,
transform_query: Query<'w, 's, &'static Transform>,
}
impl<'w, 's> TransformHelper<'w, 's> {
/// Computes the [`GlobalTransform`] of the given entity from the [`Transform`] component on it and its ancestors.
pub fn compute_global_transform(
&self,
entity: Entity,
) -> Result<GlobalTransform, ComputeGlobalTransformError> {
let transform = self
.transform_query
.get(entity)
.map_err(|err| map_error(err, false))?;
let mut global_transform = GlobalTransform::from(*transform);
for entity in self.parent_query.iter_ancestors(entity) {
let transform = self
.transform_query
.get(entity)
.map_err(|err| map_error(err, true))?;
global_transform = *transform * global_transform;
}
Ok(global_transform)
}
}
fn map_error(err: QueryEntityError, ancestor: bool) -> ComputeGlobalTransformError {
use ComputeGlobalTransformError::*;
match err {
QueryEntityError::QueryDoesNotMatch(entity) => MissingTransform(entity),
QueryEntityError::NoSuchEntity(entity) => {
if ancestor {
MalformedHierarchy(entity)
} else {
NoSuchEntity(entity)
}
}
QueryEntityError::AliasedMutability(_) => unreachable!(),
}
}
/// Error returned by [`TransformHelper::compute_global_transform`].
#[derive(Debug)]
pub enum ComputeGlobalTransformError {
/// The entity or one of its ancestors is missing the [`Transform`] component.
MissingTransform(Entity),
/// The entity does not exist.
NoSuchEntity(Entity),
/// An ancestor is missing.
/// This probably means that your hierarchy has been improperly maintained.
MalformedHierarchy(Entity),
}
#[cfg(test)]
mod tests {
use std::f32::consts::TAU;
use bevy_app::App;
use bevy_ecs::system::SystemState;
use bevy_hierarchy::BuildWorldChildren;
use bevy_math::{Quat, Vec3};
use crate::{
components::{GlobalTransform, Transform},
helper::TransformHelper,
TransformBundle, TransformPlugin,
};
#[test]
fn match_transform_propagation_systems() {
// Single transform
match_transform_propagation_systems_inner(vec![Transform::from_translation(Vec3::X)
.with_rotation(Quat::from_rotation_y(TAU / 4.))
.with_scale(Vec3::splat(2.))]);
// Transform hierarchy
match_transform_propagation_systems_inner(vec![
Transform::from_translation(Vec3::X)
.with_rotation(Quat::from_rotation_y(TAU / 4.))
.with_scale(Vec3::splat(2.)),
Transform::from_translation(Vec3::Y)
.with_rotation(Quat::from_rotation_z(TAU / 3.))
.with_scale(Vec3::splat(1.5)),
Transform::from_translation(Vec3::Z)
.with_rotation(Quat::from_rotation_x(TAU / 2.))
.with_scale(Vec3::splat(0.3)),
]);
}
fn match_transform_propagation_systems_inner(transforms: Vec<Transform>) {
let mut app = App::new();
app.add_plugins(TransformPlugin);
let mut entity = None;
for transform in transforms {
let mut e = app.world.spawn(TransformBundle::from(transform));
if let Some(entity) = entity {
e.set_parent(entity);
}
entity = Some(e.id());
}
let leaf_entity = entity.unwrap();
app.update();
let transform = *app.world.get::<GlobalTransform>(leaf_entity).unwrap();
let mut state = SystemState::<TransformHelper>::new(&mut app.world);
let helper = state.get(&app.world);
let computed_transform = helper.compute_global_transform(leaf_entity).unwrap();
approx::assert_abs_diff_eq!(transform.affine(), computed_transform.affine());
}
}

View File

@ -6,6 +6,7 @@
pub mod commands; pub mod commands;
/// The basic components of the transform crate /// The basic components of the transform crate
pub mod components; pub mod components;
pub mod helper;
/// Systems responsible for transform propagation /// Systems responsible for transform propagation
pub mod systems; pub mod systems;
@ -13,8 +14,8 @@ pub mod systems;
pub mod prelude { pub mod prelude {
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{
commands::BuildChildrenTransformExt, components::*, TransformBundle, TransformPlugin, commands::BuildChildrenTransformExt, components::*, helper::TransformHelper,
TransformPoint, TransformBundle, TransformPlugin, TransformPoint,
}; };
} }

View File

@ -378,7 +378,7 @@ pub fn winit_runner(mut app: App) {
ResMut<CanvasParentResizeEventChannel>, ResMut<CanvasParentResizeEventChannel>,
)> = SystemState::from_world(&mut app.world); )> = SystemState::from_world(&mut app.world);
let mut finished_and_setup_done = false; let mut finished_and_setup_done = app.ready();
// setup up the event loop // setup up the event loop
let event_handler = move |event: Event<()>, let event_handler = move |event: Event<()>,

View File

@ -240,6 +240,14 @@ Bevy support for WebGPU is being worked on, but is currently experimental.
To build for WebGPU, you'll need to disable default features and add all those you need, making sure to omit the `webgl2` feature. To build for WebGPU, you'll need to disable default features and add all those you need, making sure to omit the `webgl2` feature.
WebGPU depends on unstable APIs so you will also need to pass the `web_sys_unstable_apis` flag to your builds. For example:
```sh
RUSTFLAGS=--cfg=web_sys_unstable_apis cargo build ...
```
Check `wasm-bindgen` [docs on Unstable APIs](https://rustwasm.github.io/wasm-bindgen/web-sys/unstable-apis.html) for more details.
Bevy has an helper to build its examples: Bevy has an helper to build its examples:
- Build for WebGL2: `cargo run -p build-wasm-example -- --api webgl2 load_gltf` - Build for WebGL2: `cargo run -p build-wasm-example -- --api webgl2 load_gltf`

View File

@ -34,7 +34,7 @@ The default feature set enables most of the expected features of a game engine,
|png|PNG image format support| |png|PNG image format support|
|tonemapping_luts|Include tonemapping Look Up Tables KTX2 files| |tonemapping_luts|Include tonemapping Look Up Tables KTX2 files|
|vorbis|OGG/VORBIS audio format support| |vorbis|OGG/VORBIS audio format support|
|webgl2|Enable some limitations to be able to use WebGL2. If not enabled, it will default to WebGPU in Wasm| |webgl2|Enable some limitations to be able to use WebGL2. If not enabled, it will default to WebGPU in Wasm. Please refer to the [WebGL2 and WebGPU](https://github.com/bevyengine/bevy/tree/latest/examples#webgl2-and-webgpu) section of the examples README for more information on how to run Wasm builds with WebGPU.|
|x11|X11 display server support| |x11|X11 display server support|
|zstd|For KTX2 supercompression| |zstd|For KTX2 supercompression|

View File

@ -545,6 +545,14 @@ Bevy support for WebGPU is being worked on, but is currently experimental.
To build for WebGPU, you'll need to disable default features and add all those you need, making sure to omit the `webgl2` feature. To build for WebGPU, you'll need to disable default features and add all those you need, making sure to omit the `webgl2` feature.
WebGPU depends on unstable APIs so you will also need to pass the `web_sys_unstable_apis` flag to your builds. For example:
```sh
RUSTFLAGS=--cfg=web_sys_unstable_apis cargo build ...
```
Check `wasm-bindgen` [docs on Unstable APIs](https://rustwasm.github.io/wasm-bindgen/web-sys/unstable-apis.html) for more details.
Bevy has an helper to build its examples: Bevy has an helper to build its examples:
- Build for WebGL2: `cargo run -p build-wasm-example -- --api webgl2 load_gltf` - Build for WebGL2: `cargo run -p build-wasm-example -- --api webgl2 load_gltf`