Skip to content

Commit e83c13d

Browse files
committed
Simplify code
1 parent 1ccd2d6 commit e83c13d

38 files changed

+447
-337
lines changed

crates/bevy_gltf/src/loader.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ fn load_node(
475475

476476
node.insert(Camera {
477477
name: Some(base::camera::CAMERA_2D.to_owned()),
478-
projection_matrix: orthographic_projection.get_projection_matrix(),
478+
projection_matrices: vec![orthographic_projection.get_projection_matrix()],
479479
..Default::default()
480480
});
481481
node.insert(orthographic_projection);
@@ -497,10 +497,9 @@ fn load_node(
497497
}
498498
node.insert(Camera {
499499
name: Some(base::camera::CAMERA_3D.to_owned()),
500-
projection_matrix: perspective_projection.get_projection_matrix(),
500+
projection_matrices: vec![perspective_projection.get_projection_matrix()],
501501
..Default::default()
502502
});
503-
// FIXME how to differentiate between CAMERA_XR and CAMERA_3D?
504503
node.insert(perspective_projection);
505504
}
506505
}

crates/bevy_internal/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ wgpu_trace = ["bevy_wgpu/trace"]
1818
trace = [ "bevy_app/trace", "bevy_ecs/trace" ]
1919
trace_chrome = [ "bevy_log/tracing-chrome" ]
2020

21-
use-openxr = ["bevy_wgpu/use-openxr", "bevy_render/use-openxr", "bevy_openxr", "bevy_openxr_core"]
21+
use-openxr = ["bevy_wgpu/use-openxr", "bevy_openxr", "bevy_openxr_core"]
2222

2323
# Image format support for texture loading (PNG and HDR are enabled by default)
2424
hdr = ["bevy_render/hdr"]
@@ -74,7 +74,7 @@ bevy_openxr_core = { path = "../bevy_openxr_core", optional = true, version = "0
7474
bevy_sprite = { path = "../bevy_sprite", optional = true, version = "0.5.0" }
7575
bevy_text = { path = "../bevy_text", optional = true, version = "0.5.0" }
7676
bevy_ui = { path = "../bevy_ui", optional = true, version = "0.5.0" }
77-
bevy_wgpu = { path = "../bevy_wgpu", optional = true, version = "0.5.0" }
77+
bevy_wgpu = { path = "../bevy_wgpu", optional = true, default-features = false, version = "0.5.0" }
7878
bevy_winit = { path = "../bevy_winit", optional = true, version = "0.5.0" }
7979
bevy_gilrs = { path = "../bevy_gilrs", optional = true, version = "0.5.0" }
8080

crates/bevy_openxr/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ bevy_math = { path = "../bevy_math", version = "0.5.0" }
2323
bevy_openxr_core = { path = "../bevy_openxr_core", version = "0.5.0" }
2424
bevy_pbr = { path = "../bevy_pbr", version = "0.5.0" }
2525
bevy_reflect = { path = "../bevy_reflect", version = "0.5.0" }
26-
bevy_render = { path = "../bevy_render", version = "0.5.0", features = ["use-openxr"] }
26+
bevy_render = { path = "../bevy_render", version = "0.5.0" }
2727
bevy_scene = { path = "../bevy_scene", version = "0.5.0" } # FIXME not really needed, except for plugin order
2828
bevy_transform = { path = "../bevy_transform", version = "0.5.0" }
2929
bevy_utils = { path = "../bevy_utils", version = "0.5.0" }
3030
bevy_wgpu = { path = "../bevy_wgpu", version = "0.5.0", default-features = false, features = ["use-openxr"] }
31+
bevy_window = { path = "../bevy_window", version = "0.5.0" }
3132

3233
# other
3334
openxr = { path = "../../../openxrs/openxr", features = ["loaded"], default-features = false }

crates/bevy_openxr/src/lib.rs

Lines changed: 133 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
use bevy_app::{
2-
AppBuilder, Plugin, PluginGroupBuilder, ScheduleRunnerPlugin, ScheduleRunnerSettings,
2+
AppBuilder, CoreStage, Plugin, PluginGroupBuilder, ScheduleRunnerPlugin, ScheduleRunnerSettings,
33
};
44
use bevy_ecs::prelude::*;
55
use bevy_openxr_core::{
6-
event::{XRViewSurfaceCreated, XRViewsCreated},
7-
XrFovf,
6+
event::{XRCameraTransformsUpdated, XRState, XRViewSurfaceCreated, XRViewsCreated},
7+
math::XRMatrixComputation,
8+
XRConfigurationState, XRDevice,
9+
};
10+
use bevy_render::{
11+
camera::Camera,
12+
camera::CameraProjection,
13+
render_graph::{base::node, RenderGraph, WindowTextureNode},
14+
RenderPlugin, RenderStage,
815
};
9-
use bevy_render::{camera::Camera, camera::CameraProjection, RenderPlugin};
1016

1117
pub mod prelude {
1218
pub use crate::{HandPoseEvent, OpenXRPlugin, OpenXRSettings};
@@ -16,12 +22,17 @@ pub mod prelude {
1622

1723
use bevy_utils::tracing::warn;
1824
use bevy_wgpu::{WgpuBackend, WgpuOptions};
25+
use bevy_window::{CreateWindow, Window, WindowId, Windows};
1926
use openxr::HandJointLocations;
2027

2128
mod error;
2229
mod hand_tracking;
2330
mod platform;
2431
mod projection;
32+
mod xr_swapchain_node;
33+
use xr_swapchain_node::XRSwapchainNode;
34+
mod xr_window_texture_node;
35+
use xr_window_texture_node::XRWindowTextureNode;
2536

2637
pub use hand_tracking::*;
2738
pub use projection::*;
@@ -40,8 +51,7 @@ pub fn get_render_plugin() -> RenderPlugin {
4051
RenderPlugin {
4152
base_render_graph_config: Some(bevy_render::render_graph::base::BaseRenderGraphConfig {
4253
add_2d_camera: false,
43-
add_3d_camera: false,
44-
add_xr_camera: true,
54+
add_3d_camera: true,
4555
..Default::default()
4656
}),
4757
}
@@ -88,7 +98,7 @@ impl Plugin for OpenXRPlugin {
8898
))
8999
.add_plugin(ScheduleRunnerPlugin::default())
90100
.add_event::<HandPoseEvent>()
91-
.add_system(openxr_camera_system.system());
101+
.add_system_to_stage(CoreStage::PostUpdate, openxr_camera_system.system());
92102
}
93103
}
94104

@@ -112,23 +122,137 @@ fn openxr_camera_system(
112122
mut camera_query: Query<(&mut Camera, &mut XRProjection)>,
113123
mut view_surface_created_events: EventReader<XRViewSurfaceCreated>,
114124
mut views_created_events: EventReader<XRViewsCreated>,
125+
mut camera_transforms_updated: EventReader<XRCameraTransformsUpdated>,
115126
) {
127+
// FIXME: remove
116128
for event in view_surface_created_events.iter() {
117129
for (_, mut camera_projection) in camera_query.iter_mut() {
118130
// this is actually unnecessary?
119131
camera_projection.update(event.width as f32, event.height as f32);
120132
}
121133
}
122134

135+
// initialize projection matrices on view creation
123136
for event in views_created_events.iter() {
124137
for (mut camera, camera_projection) in camera_query.iter_mut() {
125-
camera.multiview_projection_matrices = event
138+
camera.depth_calculation = camera_projection.depth_calculation();
139+
camera.projection_matrices = event
126140
.views
127141
.iter()
128142
.map(|view| camera_projection.get_projection_matrix_fov(&view.fov))
129143
.collect::<Vec<_>>();
144+
}
145+
}
130146

131-
camera.depth_calculation = camera_projection.depth_calculation();
147+
for event in camera_transforms_updated.iter() {
148+
for (mut camera, _) in camera_query.iter_mut() {
149+
camera.position_matrices = event
150+
.transforms
151+
.iter()
152+
.map(|transform| transform.compute_xr_matrix())
153+
.collect::<Vec<_>>();
154+
}
155+
}
156+
}
157+
158+
pub struct OpenXRWgpuPlugin;
159+
160+
impl Plugin for OpenXRWgpuPlugin {
161+
fn build(&self, app: &mut AppBuilder) {
162+
app.add_startup_system(add_xr_render_graph.system())
163+
.add_system(handle_create_window_events.system())
164+
.add_system_to_stage(
165+
RenderStage::Draw,
166+
pre_render_system.exclusive_system(), // FIXME there should maybe be some ImmediatelyBeforeRender system
167+
)
168+
.add_system_to_stage(
169+
RenderStage::PostRender,
170+
post_render_system.exclusive_system(), // FIXME there should maybe be some ImmediatelyAfterPost system
171+
);
172+
}
173+
}
174+
175+
fn pre_render_system(
176+
mut xr_device: ResMut<XRDevice>,
177+
wgpu_handles: ResMut<bevy_wgpu::WgpuRendererHandles>,
178+
mut wgpu_render_state: ResMut<bevy_wgpu::WgpuRenderState>,
179+
mut xr_configuration_state: ResMut<XRConfigurationState>,
180+
) {
181+
let (state, texture_views) = xr_device.prepare_update(&wgpu_handles.device);
182+
183+
let should_render = if let XRState::Running = state {
184+
true
185+
} else {
186+
false
187+
};
188+
189+
if let Some(texture_views) = texture_views {
190+
xr_configuration_state.texture_views = Some(texture_views);
191+
}
192+
193+
if should_render {
194+
xr_configuration_state.next_swap_chain_index = xr_device
195+
.get_swapchain_mut()
196+
.unwrap()
197+
.get_next_swapchain_image_index();
198+
}
199+
200+
wgpu_render_state.should_render = should_render;
201+
}
202+
203+
fn post_render_system(mut xr_device: ResMut<XRDevice>) {
204+
xr_device.finalize_update();
205+
}
206+
207+
fn add_xr_render_graph(mut graph: ResMut<RenderGraph>) {
208+
let main_depth_texture: &WindowTextureNode = graph.get_node(node::MAIN_DEPTH_TEXTURE).unwrap();
209+
let descriptor = *main_depth_texture.descriptor();
210+
211+
graph
212+
.replace_node(
213+
node::MAIN_DEPTH_TEXTURE,
214+
XRWindowTextureNode::new(descriptor),
215+
)
216+
.unwrap();
217+
218+
graph
219+
.replace_node(node::PRIMARY_SWAP_CHAIN, XRSwapchainNode::new())
220+
.unwrap();
221+
222+
let main_sampled_color_attachment: &WindowTextureNode =
223+
graph.get_node(node::MAIN_SAMPLED_COLOR_ATTACHMENT).unwrap();
224+
225+
let descriptor = *main_sampled_color_attachment.descriptor();
226+
227+
graph
228+
.replace_node(
229+
node::MAIN_SAMPLED_COLOR_ATTACHMENT,
230+
XRWindowTextureNode::new(descriptor),
231+
)
232+
.unwrap();
233+
}
234+
235+
fn handle_create_window_events(
236+
mut windows: ResMut<Windows>,
237+
mut create_window_events: EventReader<CreateWindow>,
238+
// mut window_created_events: EventWriter<WindowCreated>,
239+
) {
240+
for _create_window_event in create_window_events.iter() {
241+
if let None = windows.get_primary() {
242+
windows.add(Window::new(
243+
WindowId::primary(),
244+
&Default::default(),
245+
896,
246+
1008,
247+
1.,
248+
None,
249+
));
132250
}
251+
252+
/*
253+
window_created_events.send(WindowCreated {
254+
id: create_window_event.id,
255+
});
256+
*/
133257
}
134258
}

crates/bevy_openxr/src/projection.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use bevy_ecs::bundle::Bundle;
22
use bevy_ecs::reflect::ReflectComponent;
33
use bevy_math::Mat4;
4-
use bevy_openxr_core::XrFovf;
4+
use bevy_openxr_core::{View, XrFovf};
55
use bevy_reflect::Reflect;
6-
use bevy_render::camera::{Camera, CameraProjection, DepthCalculation, VisibleEntities};
7-
use bevy_render::render_graph::base::camera::CAMERA_XR;
6+
use bevy_render::{
7+
camera::{Camera, CameraProjection, DepthCalculation, VisibleEntities},
8+
render_graph::base::camera::CAMERA_3D,
9+
};
810
use bevy_transform::components::{GlobalTransform, Transform};
911

1012
#[derive(Debug, Clone, Reflect)]
@@ -145,7 +147,7 @@ impl Default for XRCameraBundle {
145147
fn default() -> Self {
146148
XRCameraBundle {
147149
camera: Camera {
148-
name: Some(CAMERA_XR.to_string()),
150+
name: Some(CAMERA_3D.to_string()),
149151
..Default::default()
150152
},
151153
// FIXME: ..Default::default() here causes stack overflow? Wut?
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use std::{any::Any, borrow::Cow};
2+
3+
use bevy_ecs::world::World;
4+
use bevy_openxr_core::XRConfigurationState;
5+
6+
use bevy_render::{
7+
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
8+
renderer::{
9+
RenderContext, RenderResourceContext, RenderResourceId, RenderResourceType, TextureId,
10+
},
11+
};
12+
use bevy_wgpu::renderer::{WgpuRenderContext, WgpuRenderResourceContext};
13+
14+
/// Like `WindowSwapChainNode`, but for XR implementation
15+
/// XR implementation initializes the underlying textures at the startup, and after that
16+
/// this node will swap the textures based on texture id retrieved from XR swapchain
17+
#[derive(Default)]
18+
pub struct XRSwapchainNode {
19+
resource_ids: Option<Vec<(RenderResourceId, Option<wgpu::TextureView>)>>,
20+
}
21+
22+
impl XRSwapchainNode {
23+
pub const OUT_TEXTURE: &'static str = "texture";
24+
25+
pub fn new() -> Self {
26+
XRSwapchainNode::default()
27+
}
28+
}
29+
30+
impl Node for XRSwapchainNode {
31+
fn output(&self) -> &[ResourceSlotInfo] {
32+
static OUTPUT: &[ResourceSlotInfo] = &[ResourceSlotInfo {
33+
name: Cow::Borrowed(XRSwapchainNode::OUT_TEXTURE),
34+
resource_type: RenderResourceType::Texture,
35+
}];
36+
OUTPUT
37+
}
38+
39+
fn prepare(&mut self, world: &mut World) {
40+
let mut xr_configuration_state = world.get_resource_mut::<XRConfigurationState>().unwrap();
41+
if let None = self.resource_ids {
42+
// move array of textures from the swapchain into render resource context
43+
// and set textures to this node
44+
self.resource_ids = Some(
45+
xr_configuration_state
46+
.texture_views
47+
.take()
48+
.unwrap()
49+
.into_iter()
50+
.map(|texture_view| {
51+
(
52+
RenderResourceId::Texture(TextureId::new()),
53+
Some(texture_view),
54+
)
55+
})
56+
.collect(),
57+
);
58+
}
59+
}
60+
61+
fn update(
62+
&mut self,
63+
world: &World,
64+
render_context: &mut dyn RenderContext,
65+
_input: &ResourceSlots,
66+
output: &mut ResourceSlots,
67+
) {
68+
const WINDOW_TEXTURE: usize = 0;
69+
let xr_configuration_state = world.get_resource::<XRConfigurationState>().unwrap();
70+
71+
// get next texture by id
72+
let render_resource_id = self
73+
.resource_ids
74+
.as_mut()
75+
.unwrap()
76+
.get_mut(xr_configuration_state.next_swap_chain_index)
77+
.unwrap();
78+
79+
if let Some(texture_view) = render_resource_id.1.take() {
80+
if let RenderResourceId::Texture(texture_id) = render_resource_id.0 {
81+
let render_resource_context = render_context.resources_mut();
82+
83+
let render_resource_context = render_resource_context
84+
.downcast_mut::<WgpuRenderResourceContext>()
85+
.unwrap();
86+
87+
render_resource_context.add_wgpu_texture_view(texture_id, texture_view);
88+
}
89+
}
90+
91+
// set output to desired resource id
92+
output.set(WINDOW_TEXTURE, render_resource_id.0.clone());
93+
}
94+
}

crates/bevy_render/src/render_graph/nodes/xr_window_texture_node.rs renamed to crates/bevy_openxr/src/xr_window_texture_node.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use crate::{
1+
use bevy_app::{Events, ManualEventReader};
2+
use bevy_ecs::world::World;
3+
use bevy_openxr_core::event::XRViewSurfaceCreated;
4+
use bevy_render::{
25
render_graph::{Node, ResourceSlotInfo, ResourceSlots, WindowTextureNode},
36
renderer::{RenderContext, RenderResourceId, RenderResourceType},
47
texture::TextureDescriptor,
58
};
6-
use bevy_app::{Events, ManualEventReader};
7-
use bevy_ecs::world::World;
8-
use bevy_openxr_core::event::XRViewSurfaceCreated;
99
use std::borrow::Cow;
1010

1111
/// MAIN_SAMPLED_COLOR_ATTACHMENT node in OpenXR implementation, used instead of `WindowTextureNode`
@@ -35,7 +35,7 @@ impl Node for XRWindowTextureNode {
3535

3636
fn update(
3737
&mut self,
38-
world: &mut World,
38+
world: &World,
3939
render_context: &mut dyn RenderContext,
4040
_input: &ResourceSlots,
4141
output: &mut ResourceSlots,

0 commit comments

Comments
 (0)