Offscreen rendering with view swap
This commit is contained in:
parent
13a912d228
commit
87cf72bbe5
2 changed files with 95 additions and 185 deletions
62
src/main.rs
62
src/main.rs
|
@ -106,9 +106,6 @@ fn update_ui_side_panel(
|
|||
mut global_state: ResMut<GlobalState>,
|
||||
mut object_infos: ResMut<ObjectInfos>,
|
||||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut standard_materials: ResMut<Assets<StandardMaterial>>,
|
||||
mut color_materials: ResMut<Assets<ColorMaterial>>,
|
||||
) {
|
||||
let offscreen_texture_id = contexts.image_id(&global_state.offscreen_image).unwrap();
|
||||
|
||||
|
@ -127,32 +124,53 @@ fn update_ui_side_panel(
|
|||
if ui.button("Change to 3D View").clicked() {
|
||||
global_state.view_2d = false;
|
||||
|
||||
// object_infos.iter_mut().for_each(|polygon| {
|
||||
// polygon.swap_to_3d(
|
||||
// &global_state,
|
||||
// &mut commands,
|
||||
// &mut meshes,
|
||||
// &mut standard_materials,
|
||||
// )
|
||||
// });
|
||||
// remove render layer and add camera with default render target
|
||||
let mut cam_3d = commands.entity(global_state.camera_3d);
|
||||
cam_3d.remove::<RenderLayers>();
|
||||
cam_3d.remove::<Camera>();
|
||||
cam_3d.insert(Camera::default());
|
||||
|
||||
// add render layer and add camera with offscreen render target
|
||||
let mut cam_2d = commands.entity(global_state.camera_2d);
|
||||
cam_2d.insert(global_state.offscreen_render_layer);
|
||||
cam_2d.remove::<Camera>();
|
||||
cam_2d.insert(Camera {
|
||||
target: RenderTarget::Image(global_state.offscreen_image.clone()),
|
||||
..default()
|
||||
});
|
||||
|
||||
object_infos
|
||||
.iter_mut()
|
||||
.for_each(|polygon| polygon.swap_to_3d(&global_state, &mut commands));
|
||||
}
|
||||
} else {
|
||||
if ui.button("Change to 2D View").clicked() {
|
||||
global_state.view_2d = true;
|
||||
|
||||
// object_infos.iter_mut().for_each(|polygon| {
|
||||
// polygon.swap_to_2d(
|
||||
// &global_state,
|
||||
// &mut commands,
|
||||
// &mut meshes,
|
||||
// &mut color_materials,
|
||||
// )
|
||||
// });
|
||||
// add render layer and add camera with offscreen render target
|
||||
let mut cam_3d = commands.entity(global_state.camera_3d);
|
||||
cam_3d.insert(global_state.offscreen_render_layer);
|
||||
cam_3d.remove::<Camera>();
|
||||
cam_3d.insert(Camera {
|
||||
target: RenderTarget::Image(global_state.offscreen_image.clone()),
|
||||
..default()
|
||||
});
|
||||
|
||||
// remove render layer and add camera with default render target
|
||||
let mut cam_2d = commands.entity(global_state.camera_2d);
|
||||
cam_2d.remove::<RenderLayers>();
|
||||
cam_2d.remove::<Camera>();
|
||||
cam_2d.insert(Camera::default());
|
||||
|
||||
object_infos
|
||||
.iter_mut()
|
||||
.for_each(|polygon| polygon.swap_to_2d(&global_state, &mut commands));
|
||||
}
|
||||
}
|
||||
|
||||
if global_state.view_2d {
|
||||
if global_state.polygon_started {
|
||||
// print list of coordinates of current polygon
|
||||
if let Some(polygon) = object_infos.active_polygon() {
|
||||
for (index, point) in polygon.points().iter().enumerate() {
|
||||
ui.label(&format!("{}: ({}, {})", index, point.x, point.y));
|
||||
|
@ -228,9 +246,11 @@ fn on_resize_system(
|
|||
// When resolution is being changed
|
||||
global_state.window_extent = Vec2::new(e.width, e.height);
|
||||
|
||||
let center = (global_state.window_extent * 0.5).extend(0.0);
|
||||
|
||||
for mut transform in &mut camera {
|
||||
*transform = Transform::from_xyz(200.0, -600.0, 600.0)
|
||||
.looking_at((global_state.window_extent * 0.5).extend(0.0), Vec3::Z);
|
||||
*transform = Transform::from_xyz(center.x + 200.0, center.y - 600.0, 600.0)
|
||||
.looking_at(center, Vec3::Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
218
src/polygon.rs
218
src/polygon.rs
|
@ -2,7 +2,7 @@ use std::slice::IterMut;
|
|||
|
||||
use bevy::{
|
||||
prelude::*,
|
||||
render::{mesh::Indices, render_resource::PrimitiveTopology},
|
||||
render::{mesh::Indices, render_resource::PrimitiveTopology, view::RenderLayers},
|
||||
sprite::MaterialMesh2dBundle,
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,10 @@ struct CollectionIDs {
|
|||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct FinishedIDs {
|
||||
// 2d plane
|
||||
plane: Entity,
|
||||
|
||||
// 3d object
|
||||
object: Entity,
|
||||
}
|
||||
|
||||
|
@ -50,178 +53,65 @@ pub struct Polygon {
|
|||
impl Polygon {
|
||||
const PROXIMITY_THRESHOLD: f32 = 10.0;
|
||||
|
||||
// pub fn swap_to_3d(
|
||||
// &mut self,
|
||||
// global_state: &GlobalState,
|
||||
// commands: &mut Commands,
|
||||
// meshes: &mut ResMut<Assets<Mesh>>,
|
||||
// materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
// ) {
|
||||
// debug_assert!(self.state.is_2d());
|
||||
pub fn swap_to_3d(&mut self, global_state: &GlobalState, commands: &mut Commands) {
|
||||
match &self.state {
|
||||
PolygonState::Collection(collection_ids) => {
|
||||
// add render layer to all points
|
||||
for point in collection_ids.points.iter() {
|
||||
let mut handle = commands.entity(*point);
|
||||
|
||||
// // clear all 2d entities
|
||||
// let finished = match self.state.two_dimensional_mut() {
|
||||
// PolygonState::Collection(collection_ids) => {
|
||||
// for point in collection_ids.points.iter() {
|
||||
// commands.entity(*point).despawn();
|
||||
// }
|
||||
handle.insert(global_state.offscreen_render_layer);
|
||||
}
|
||||
|
||||
// for line in collection_ids.lines.iter() {
|
||||
// commands.entity(*line).despawn();
|
||||
// }
|
||||
// also add render layer to all lines
|
||||
for line in collection_ids.points.iter() {
|
||||
let mut handle = commands.entity(*line);
|
||||
|
||||
// false
|
||||
// }
|
||||
// PolygonState::Finished(mesh) => {
|
||||
// commands.entity(*mesh).despawn();
|
||||
handle.insert(global_state.offscreen_render_layer);
|
||||
}
|
||||
}
|
||||
PolygonState::Finished(finished_ids) => {
|
||||
// add render layer to 2d plane
|
||||
commands
|
||||
.entity(finished_ids.plane)
|
||||
.insert(global_state.offscreen_render_layer);
|
||||
|
||||
// true
|
||||
// }
|
||||
// };
|
||||
// remove render layer from 3d object
|
||||
commands
|
||||
.entity(finished_ids.object)
|
||||
.remove::<RenderLayers>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// self.state = PolygonView::ThreeDimensional(if finished {
|
||||
// let vertices: Vec<Vec3> = self
|
||||
// .points
|
||||
// .iter()
|
||||
// .map(|p| vec![p.extend(0.0), p.extend(global_state.extrusion_height)])
|
||||
// .flatten()
|
||||
// .collect();
|
||||
pub fn swap_to_2d(&mut self, global_state: &GlobalState, commands: &mut Commands) {
|
||||
match &self.state {
|
||||
PolygonState::Collection(collection_ids) => {
|
||||
// remove render layer from all points
|
||||
for point in collection_ids.points.iter() {
|
||||
let mut handle = commands.entity(*point);
|
||||
|
||||
// let indices = Indices::U32({
|
||||
// let mut v = Vec::new();
|
||||
handle.remove::<RenderLayers>();
|
||||
}
|
||||
|
||||
// for i in 0..self.points.len() {
|
||||
// let index = (i as u32) * 2;
|
||||
// remove render layer from all lines
|
||||
for line in collection_ids.points.iter() {
|
||||
let mut handle = commands.entity(*line);
|
||||
|
||||
// // create quads from 4 adjacent points
|
||||
// v.push(index);
|
||||
// v.push((index + 2) % vertices.len() as u32);
|
||||
// v.push(index + 1);
|
||||
// v.push(index + 1);
|
||||
// v.push((index + 2) % vertices.len() as u32);
|
||||
// v.push((index + 3) % vertices.len() as u32);
|
||||
// }
|
||||
handle.remove::<RenderLayers>();
|
||||
}
|
||||
}
|
||||
PolygonState::Finished(finished_ids) => {
|
||||
// remove render layer from 2d plane
|
||||
commands.entity(finished_ids.plane).remove::<RenderLayers>();
|
||||
|
||||
// // TODO: proper ear cutting algo
|
||||
// for i in 2..self.points.len() as u32 {
|
||||
// let index = (i as u32) * 2 + 1;
|
||||
|
||||
// v.push(1);
|
||||
// v.push(index - 2);
|
||||
// v.push(index);
|
||||
// }
|
||||
|
||||
// v
|
||||
// });
|
||||
|
||||
// let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
|
||||
// mesh.set_indices(Some(indices));
|
||||
// mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices);
|
||||
|
||||
// let mesh_id = commands
|
||||
// .spawn(MaterialMeshBundle {
|
||||
// mesh: meshes.add(mesh).into(),
|
||||
// transform: Transform::default(),
|
||||
// material: materials.add(StandardMaterial::from(Color::BLACK)),
|
||||
// ..default()
|
||||
// })
|
||||
// .id();
|
||||
|
||||
// Some(mesh_id)
|
||||
// } else {
|
||||
// None
|
||||
// });
|
||||
// }
|
||||
|
||||
// pub fn swap_to_2d(
|
||||
// &mut self,
|
||||
// global_state: &GlobalState,
|
||||
// commands: &mut Commands,
|
||||
// meshes: &mut ResMut<Assets<Mesh>>,
|
||||
// materials: &mut ResMut<Assets<ColorMaterial>>,
|
||||
// ) {
|
||||
// debug_assert!(self.state.is_3d());
|
||||
|
||||
// // clear 3d entity
|
||||
|
||||
// let finished = match self.state.three_dimensional_mut() {
|
||||
// Some(mesh_id) => {
|
||||
// commands.entity(*mesh_id).despawn();
|
||||
|
||||
// true
|
||||
// }
|
||||
// None => false,
|
||||
// };
|
||||
|
||||
// self.state = PolygonView::TwoDimensional(if finished {
|
||||
// // create triangle mesh
|
||||
// let triangle_mesh = self.create_triangulated_mesh();
|
||||
|
||||
// let triangle_id = commands
|
||||
// .spawn(MaterialMesh2dBundle {
|
||||
// mesh: meshes.add(triangle_mesh).into(),
|
||||
// transform: Transform::default()
|
||||
// .with_translation((-global_state.window_extent * 0.5).extend(0.0)),
|
||||
// material: materials.add(ColorMaterial::from(Color::BLACK)),
|
||||
// ..default()
|
||||
// })
|
||||
// .id();
|
||||
|
||||
// // store triangle entity id in state
|
||||
// PolygonState::Finished(triangle_id)
|
||||
// } else {
|
||||
// // create point meshes for every point
|
||||
// let point_ids = self
|
||||
// .points
|
||||
// .iter()
|
||||
// .map(|&point| {
|
||||
// commands
|
||||
// .spawn(MaterialMesh2dBundle {
|
||||
// mesh: meshes.add(Mesh::from(shape::Quad::default())).into(),
|
||||
// transform: Transform::default()
|
||||
// .with_scale(Vec3::splat(4.0))
|
||||
// .with_translation(
|
||||
// (point - (global_state.window_extent * 0.5)).extend(0.0),
|
||||
// ),
|
||||
// material: materials.add(ColorMaterial::from(Color::BLACK)),
|
||||
// ..default()
|
||||
// })
|
||||
// .id()
|
||||
// })
|
||||
// .collect();
|
||||
|
||||
// // draw lines between the points
|
||||
// let line_ids = (1..self.points.len())
|
||||
// .map(|i| {
|
||||
// let previous_point = self.points[i - 1];
|
||||
// let point = self.points[i];
|
||||
|
||||
// let a = Vec2::X.angle_between((point - previous_point).normalize());
|
||||
|
||||
// commands
|
||||
// .spawn(MaterialMesh2dBundle {
|
||||
// mesh: meshes
|
||||
// .add(Self::create_line_mesh(previous_point, point))
|
||||
// .into(),
|
||||
// transform: Transform::default()
|
||||
// .with_translation(
|
||||
// (previous_point - (global_state.window_extent * 0.5))
|
||||
// .extend(0.0),
|
||||
// )
|
||||
// .with_rotation(Quat::from_rotation_z(a)),
|
||||
// material: materials.add(ColorMaterial::from(Color::BLACK)),
|
||||
// ..default()
|
||||
// })
|
||||
// .id()
|
||||
// })
|
||||
// .collect();
|
||||
|
||||
// PolygonState::Collection(CollectionIDs {
|
||||
// points: point_ids,
|
||||
// lines: line_ids,
|
||||
// })
|
||||
// });
|
||||
// }
|
||||
// add render layer to 3d object
|
||||
commands
|
||||
.entity(finished_ids.object)
|
||||
.insert(global_state.offscreen_render_layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn points(&self) -> &[Vec2] {
|
||||
&self.points
|
||||
|
|
Loading…
Reference in a new issue