mirror of
https://github.com/Astatin3/rushroom.git
synced 2026-06-08 16:18:04 -06:00
Add serde serialisation
This commit is contained in:
+1
-1
@@ -12,8 +12,8 @@ eframe = { version = "0.29.1", features = [
|
|||||||
"persistence",]}
|
"persistence",]}
|
||||||
|
|
||||||
egui = { version = "0.29.1", features = ["callstack", "default", "log"] }
|
egui = { version = "0.29.1", features = ["callstack", "default", "log"] }
|
||||||
erased-serde = "0.4.5"
|
|
||||||
glam = "0.29.2"
|
glam = "0.29.2"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
serde = { version = "1.0.215", features = ["derive"] }
|
serde = { version = "1.0.215", features = ["derive"] }
|
||||||
serde_json = "1.0.133"
|
serde_json = "1.0.133"
|
||||||
|
typetag = "0.2.18"
|
||||||
|
|||||||
+8
-8
@@ -27,18 +27,18 @@ impl App {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
Some(Self {
|
Some(Self {
|
||||||
pane_manager: PaneManager::new(Some(cc)),
|
pane_manager: PaneManager::new(cc),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for App {
|
// impl Default for App {
|
||||||
fn default() -> Self {
|
// fn default() -> Self {
|
||||||
Self {
|
// Self {
|
||||||
pane_manager: PaneManager::new(None),
|
// pane_manager: PaneManager::new(None),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
/// Called each time the UI needs repainting, which may be many times per second.
|
/// Called each time the UI needs repainting, which may be many times per second.
|
||||||
|
|||||||
+104
-488
@@ -1,4 +1,6 @@
|
|||||||
use egui::{Ui, Color32, Stroke};
|
use egui::{Ui, Color32, Stroke};
|
||||||
|
use eframe::egui_glow::glow;
|
||||||
|
use std::sync::Arc;
|
||||||
// use erased_serde::serialize_trait_object;
|
// use erased_serde::serialize_trait_object;
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize, PartialEq)]
|
#[derive(serde::Deserialize, serde::Serialize, PartialEq)]
|
||||||
@@ -11,14 +13,20 @@ pub enum PaneMode {
|
|||||||
Center,
|
Center,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[typetag::serde(tag = "type")]
|
||||||
pub trait Pane {
|
pub trait Pane {
|
||||||
fn new(cc: &eframe::CreationContext<'_>) -> PaneState where Self: Sized;
|
fn new() -> PaneState where Self: Sized;
|
||||||
|
fn init(&mut self, pcc: &PsudoCreationContext);
|
||||||
fn name(&mut self) -> &str;
|
fn name(&mut self) -> &str;
|
||||||
fn render(&mut self, ui: &mut Ui);
|
fn render(&mut self, ui: &mut Ui);
|
||||||
fn context_menu(&mut self, ui: &mut Ui);
|
fn context_menu(&mut self, ui: &mut Ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(serde::Deserialize, serde::Serialize)]
|
// impl Deserializer for Pane {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, serde::Serialize)]
|
||||||
pub struct PaneState {
|
pub struct PaneState {
|
||||||
// #[serde(skip)]
|
// #[serde(skip)]
|
||||||
pub pane: Box<dyn Pane>,
|
pub pane: Box<dyn Pane>,
|
||||||
@@ -27,12 +35,30 @@ pub struct PaneState {
|
|||||||
// pub window_location: Pos2,
|
// pub window_location: Pos2,
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub struct NoPane {}
|
|
||||||
// impl Pane for NoPane {
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
// fn name(&mut self) -> &str {"ERROR"}
|
pub struct NoPane {}
|
||||||
// fn render(&mut self, _ui: &mut Ui){}
|
#[typetag::serde]
|
||||||
// fn context_menu(&mut self, _ui: &mut Ui) {}
|
impl Pane for NoPane {
|
||||||
// }
|
fn new() -> PaneState where Self: Sized {
|
||||||
|
let mut s = Self {};
|
||||||
|
PaneState {
|
||||||
|
id: s.name().to_string(),
|
||||||
|
mode: PaneMode::Left,
|
||||||
|
pane: Box::new(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn init(&mut self, _pcc: &PsudoCreationContext) {}
|
||||||
|
fn name(&mut self) -> &str {"ERROR"}
|
||||||
|
fn render(&mut self, _ui: &mut Ui){}
|
||||||
|
fn context_menu(&mut self, _ui: &mut Ui) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaneState {
|
||||||
|
pub fn render(&mut self, ui: &mut Ui) {
|
||||||
|
self.pane.render(ui);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// impl Default for dyn Pane {
|
// impl Default for dyn Pane {
|
||||||
@@ -41,28 +67,19 @@ pub struct PaneState {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl PaneState {
|
|
||||||
pub fn render(&mut self, ui: &mut Ui) {
|
|
||||||
self.pane.render(ui);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub struct PaneGroup {
|
// pub struct PaneGroup {
|
||||||
// pub direction: TileDirection,
|
// pub direction: TileDirection,
|
||||||
// pub panes: Vec<PaneState>,
|
// pub panes: Vec<PaneState>,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// #[derive(serde::Deserialize, serde::Serialize)]
|
// #[derive(serde::Deserialize, serde::Serialize)]
|
||||||
pub struct PaneManager {
|
// #[derive(serde::Deserialize, serde::Serialize)]
|
||||||
pub panes: Vec<PaneState>,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
pub struct BluePane {}
|
pub struct BluePane {}
|
||||||
|
#[typetag::serde]
|
||||||
impl Pane for BluePane {
|
impl Pane for BluePane {
|
||||||
fn new(cc: &eframe::CreationContext<'_>) -> PaneState where Self: Sized {
|
fn new() -> PaneState where Self: Sized {
|
||||||
|
|
||||||
let mut s = Self {};
|
let mut s = Self {};
|
||||||
PaneState {
|
PaneState {
|
||||||
id: s.name().to_string(),
|
id: s.name().to_string(),
|
||||||
@@ -70,6 +87,7 @@ impl Pane for BluePane {
|
|||||||
pane: Box::new(s),
|
pane: Box::new(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn init(&mut self, _pcc: &PsudoCreationContext){}
|
||||||
fn name(&mut self) -> &str {"BLUE"}
|
fn name(&mut self) -> &str {"BLUE"}
|
||||||
fn render(&mut self, ui: &mut Ui){
|
fn render(&mut self, ui: &mut Ui){
|
||||||
ui.painter().rect(ui.max_rect(), 0., Color32::BLUE, Stroke::NONE);
|
ui.painter().rect(ui.max_rect(), 0., Color32::BLUE, Stroke::NONE);
|
||||||
@@ -77,9 +95,12 @@ impl Pane for BluePane {
|
|||||||
fn context_menu(&mut self, _ui: &mut Ui) {}
|
fn context_menu(&mut self, _ui: &mut Ui) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
pub struct GreenPane {}
|
pub struct GreenPane {}
|
||||||
|
#[typetag::serde]
|
||||||
impl Pane for GreenPane {
|
impl Pane for GreenPane {
|
||||||
fn new(cc: &eframe::CreationContext<'_>) -> PaneState where Self: Sized {
|
fn new() -> PaneState where Self: Sized {
|
||||||
let mut s = Self {};
|
let mut s = Self {};
|
||||||
PaneState {
|
PaneState {
|
||||||
id: s.name().to_string(),
|
id: s.name().to_string(),
|
||||||
@@ -87,6 +108,7 @@ impl Pane for GreenPane {
|
|||||||
pane: Box::new(s),
|
pane: Box::new(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn init(&mut self, _cc: &PsudoCreationContext){}
|
||||||
fn name(&mut self) -> &str {"Green"}
|
fn name(&mut self) -> &str {"Green"}
|
||||||
fn render(&mut self, ui: &mut Ui){
|
fn render(&mut self, ui: &mut Ui){
|
||||||
ui.painter().rect(ui.max_rect(), 0., Color32::GREEN, Stroke::NONE);
|
ui.painter().rect(ui.max_rect(), 0., Color32::GREEN, Stroke::NONE);
|
||||||
@@ -94,26 +116,40 @@ impl Pane for GreenPane {
|
|||||||
fn context_menu(&mut self, _ui: &mut Ui) {}
|
fn context_menu(&mut self, _ui: &mut Ui) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PsudoCreationContext {
|
||||||
|
pub gl: Option<Arc<glow::Context>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PaneManager {
|
||||||
|
pcc: PsudoCreationContext,
|
||||||
|
pub panes: Vec<PaneState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl PaneManager {
|
impl PaneManager {
|
||||||
pub fn new(cc: Option<&eframe::CreationContext<'_>>) -> Self {
|
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
||||||
if let Some(cc) = cc {
|
// if let Some(cc) = cc {
|
||||||
Self {
|
|
||||||
panes: vec![
|
let mut panes = vec![
|
||||||
BluePane::new(cc),
|
BluePane::new(),
|
||||||
GreenPane::new(cc),
|
GreenPane::new(),
|
||||||
// PaneState {pane: Box::new(BluePane{}), id: "iqnhjqnbekjq".to_string(), mode: PaneMode::Windowed},
|
crate::point_cloud_renderer::PointRendererPane::new(),
|
||||||
// PaneState {pane: Box::new(GreenPane{}), id: "kjwkjwqfd".to_string(), mode: PaneMode::Right},
|
];
|
||||||
crate::point_cloud_renderer::PointRendererPane::new(cc),
|
|
||||||
],
|
let pcc = PsudoCreationContext {
|
||||||
}
|
gl: cc.gl.clone(),
|
||||||
} else {
|
};
|
||||||
Self {
|
|
||||||
panes: vec![]
|
for pane in &mut panes {
|
||||||
}
|
pane.pane.init(&pcc);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pcc,
|
||||||
|
panes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn render(&mut self, ui: &mut Ui){
|
pub fn render(&mut self, ui: &mut Ui){
|
||||||
let len = self.panes.len();
|
let len = self.panes.len();
|
||||||
|
|
||||||
@@ -125,6 +161,8 @@ impl PaneManager {
|
|||||||
egui::widgets::global_theme_preference_switch(ui);
|
egui::widgets::global_theme_preference_switch(ui);
|
||||||
|
|
||||||
ui.menu_button("File", |ui| {
|
ui.menu_button("File", |ui| {
|
||||||
|
if ui.button("Save Layout").clicked() {self.save_layout();}
|
||||||
|
if ui.button("Load Layout").clicked() {self.load_layout();}
|
||||||
if ui.button("Quit").clicked() {
|
if ui.button("Quit").clicked() {
|
||||||
ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close);
|
ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close);
|
||||||
}
|
}
|
||||||
@@ -162,9 +200,16 @@ impl PaneManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
// self.
|
|
||||||
|
for i in 0..len {
|
||||||
|
ui.menu_button(self.panes[i].id.clone(), |ui| {
|
||||||
|
let pane: &mut PaneState = &mut self.panes[i];
|
||||||
|
if pane.mode != PaneMode::Hidden {
|
||||||
|
pane.pane.context_menu(ui);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -211,452 +256,23 @@ impl PaneManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn save_layout(&self) {
|
||||||
|
if let Ok(json) = serde_json::to_string_pretty(&self.panes) {
|
||||||
|
let _ = std::fs::write("pane_layout.json", json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_layout(&mut self) {
|
||||||
|
if let Ok(panes) = std::fs::read_to_string("pane_layout.json") {
|
||||||
|
if let Ok(panes) = serde_json::from_str(&panes) {
|
||||||
|
|
||||||
|
self.panes = panes;
|
||||||
|
|
||||||
|
for (mut pane) in &mut self.panes {
|
||||||
|
pane.pane.init(&self.pcc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// use eframe::egui;
|
|
||||||
// use egui::Stroke;
|
|
||||||
// use serde::{Deserialize, Serialize};
|
|
||||||
// use std::collections::HashMap;
|
|
||||||
// use std::fs;
|
|
||||||
// use egui::Color32;
|
|
||||||
|
|
||||||
// #[derive(Serialize, Deserialize, Clone, PartialEq)]
|
|
||||||
// enum PaneMode {
|
|
||||||
// Hidden,
|
|
||||||
// Tiled,
|
|
||||||
// Windowed,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Serialize, Deserialize, Clone, PartialEq)]
|
|
||||||
// enum SplitDirection {
|
|
||||||
// Horizontal,
|
|
||||||
// Vertical,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Serialize, Deserialize, Clone)]
|
|
||||||
// struct GroupNode {
|
|
||||||
// direction: SplitDirection,
|
|
||||||
// children: Vec<LayoutNode>,
|
|
||||||
// sizes: Vec<f32>, // Stores the relative sizes of children
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Serialize, Deserialize, Clone)]
|
|
||||||
// enum LayoutNode {
|
|
||||||
// Pane(String), // Stores pane identifier
|
|
||||||
// Group(GroupNode),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Serialize, Deserialize, Clone)]
|
|
||||||
// struct LayoutConfig {
|
|
||||||
// root: Option<LayoutNode>,
|
|
||||||
// windowed_panes: HashMap<String, WindowedPaneConfig>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Serialize, Deserialize, Clone)]
|
|
||||||
// struct WindowedPaneConfig {
|
|
||||||
// position: [f32; 2],
|
|
||||||
// size: [f32; 2],
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub trait Pane {
|
|
||||||
// fn name(&self) -> &str;
|
|
||||||
// fn show(&mut self, ui: &mut egui::Ui);
|
|
||||||
// fn default_size(&self) -> egui::Vec2;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Example panes implementation
|
|
||||||
// struct ConsolePane {
|
|
||||||
// content: String,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Pane for ConsolePane {
|
|
||||||
// fn name(&self) -> &str { "Console" }
|
|
||||||
// fn show(&mut self, ui: &mut egui::Ui) {
|
|
||||||
// ui.painter().rect(ui.max_rect(), 0., Color32::RED, Stroke::NONE);
|
|
||||||
// ui.text_edit_multiline(&mut self.content);
|
|
||||||
// }
|
|
||||||
// fn default_size(&self) -> egui::Vec2 { egui::vec2(300.0, 200.0) }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// struct PropertiesPane {
|
|
||||||
// value: f32,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Pane for PropertiesPane {
|
|
||||||
// fn name(&self) -> &str { "Properties" }
|
|
||||||
// fn show(&mut self, ui: &mut egui::Ui) {
|
|
||||||
// ui.painter().rect(ui.max_rect(), 0., Color32::BLUE, Stroke::NONE);
|
|
||||||
// ui.add(egui::Slider::new(&mut self.value, 0.0..=100.0));
|
|
||||||
// }
|
|
||||||
// fn default_size(&self) -> egui::Vec2 { egui::vec2(200.0, 300.0) }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// struct DragState {
|
|
||||||
// dragged_pane: String,
|
|
||||||
// original_group_path: Vec<usize>,
|
|
||||||
// drag_started: bool,
|
|
||||||
// drop_target: Option<DropTarget>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Clone)]
|
|
||||||
// struct DropTarget {
|
|
||||||
// target_pane: String,
|
|
||||||
// group_path: Vec<usize>,
|
|
||||||
// position: DropPosition,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Clone, PartialEq)]
|
|
||||||
// enum DropPosition {
|
|
||||||
// Above,
|
|
||||||
// Below,
|
|
||||||
// Left,
|
|
||||||
// Right,
|
|
||||||
// Center,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub struct PaneManager {
|
|
||||||
// panes: HashMap<String, Box<dyn Pane>>,
|
|
||||||
// layout: LayoutConfig,
|
|
||||||
// drag_state: Option<DragState>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl PaneManager {
|
|
||||||
// pub fn new() -> Self {
|
|
||||||
// let mut panes: HashMap<String, Box<dyn Pane>> = HashMap::new();
|
|
||||||
// panes.insert("properties".to_string(), Box::new(PropertiesPane { value: 50.0 }));
|
|
||||||
// panes.insert("console".to_string(), Box::new(ConsolePane { content: String::new() }));
|
|
||||||
|
|
||||||
// // Create initial layout
|
|
||||||
// let initial_group = GroupNode {
|
|
||||||
// direction: SplitDirection::Vertical,
|
|
||||||
// children: vec![
|
|
||||||
// LayoutNode::Pane("console".to_string()),
|
|
||||||
// LayoutNode::Pane("properties".to_string()),
|
|
||||||
// ],
|
|
||||||
// sizes: vec![0.5, 0.5],
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let layout = LayoutConfig {
|
|
||||||
// root: Some(LayoutNode::Group(initial_group)),
|
|
||||||
// windowed_panes: HashMap::new(),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Self {
|
|
||||||
// panes,
|
|
||||||
// layout,
|
|
||||||
// drag_state: None,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn save_layout(&self) {
|
|
||||||
// if let Ok(json) = serde_json::to_string_pretty(&self.layout) {
|
|
||||||
// let _ = fs::write("layout.json", json);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn load_layout(&mut self) {
|
|
||||||
// if let Ok(contents) = fs::read_to_string("layout.json") {
|
|
||||||
// if let Ok(layout) = serde_json::from_str(&contents) {
|
|
||||||
// self.layout = layout;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn handle_drop(&mut self) {
|
|
||||||
// if let Some(drag_state) = &self.drag_state {
|
|
||||||
// if let Some(drop_target) = &drag_state.drop_target {
|
|
||||||
// let mut new_layout = self.layout.clone();
|
|
||||||
|
|
||||||
// // Remove dragged pane from original location
|
|
||||||
// self.remove_pane_from_path(&mut new_layout.root, &drag_state.original_group_path, &drag_state.dragged_pane);
|
|
||||||
|
|
||||||
// // Insert at new location based on drop position
|
|
||||||
// self.insert_pane_at_target(
|
|
||||||
// &mut new_layout.root,
|
|
||||||
// &drop_target.group_path,
|
|
||||||
// &drop_target.target_pane,
|
|
||||||
// &drag_state.dragged_pane,
|
|
||||||
// &drop_target.position,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// self.layout = new_layout;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// self.drag_state = None;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn remove_pane_from_path(
|
|
||||||
// &self,
|
|
||||||
// node: &mut Option<LayoutNode>,
|
|
||||||
// path: &[usize],
|
|
||||||
// pane_id: &str,
|
|
||||||
// ) -> bool {
|
|
||||||
// if path.is_empty() {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if let Some(LayoutNode::Group(group)) = node {
|
|
||||||
// if path.len() == 1 {
|
|
||||||
// if let Some(idx) = group.children.iter().position(|child| {
|
|
||||||
// matches!(child, LayoutNode::Pane(id) if id == pane_id)
|
|
||||||
// }) {
|
|
||||||
// group.children.remove(idx);
|
|
||||||
// group.sizes.remove(idx);
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// } else if path[0] < group.children.len() {
|
|
||||||
// return self.remove_pane_from_path(
|
|
||||||
// &mut Some(group.children[path[0]].clone()),
|
|
||||||
// &path[1..],
|
|
||||||
// pane_id,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// false
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn insert_pane_at_target(
|
|
||||||
// &self,
|
|
||||||
// node: &mut Option<LayoutNode>,
|
|
||||||
// path: &[usize],
|
|
||||||
// target_pane: &str,
|
|
||||||
// dragged_pane: &str,
|
|
||||||
// position: &DropPosition,
|
|
||||||
// ) {
|
|
||||||
// if let Some(LayoutNode::Group(group)) = node {
|
|
||||||
// if path.len() == 1 {
|
|
||||||
// let target_idx = group.children.iter().position(|child| {
|
|
||||||
// matches!(child, LayoutNode::Pane(id) if id == target_pane)
|
|
||||||
// }).unwrap();
|
|
||||||
// // if target_idx.is_none(){ return; }
|
|
||||||
// // target_idx = target_idx.unwrap();
|
|
||||||
// // target_idx = target_idx.unwrap();
|
|
||||||
|
|
||||||
// match (position, &group.direction) {
|
|
||||||
// (DropPosition::Above | DropPosition::Below, SplitDirection::Vertical)
|
|
||||||
// | (DropPosition::Left | DropPosition::Right, SplitDirection::Horizontal) => {
|
|
||||||
// // Insert in same group
|
|
||||||
// let insert_idx = if matches!(position, DropPosition::Below | DropPosition::Right) {
|
|
||||||
// target_idx + 1
|
|
||||||
// } else {
|
|
||||||
// target_idx
|
|
||||||
// };
|
|
||||||
// group.children.insert(insert_idx, LayoutNode::Pane(dragged_pane.to_string()));
|
|
||||||
// group.sizes.insert(insert_idx, 1.0 / (group.sizes.len() + 1) as f32);
|
|
||||||
// // Normalize sizes
|
|
||||||
// let total: f32 = group.sizes.iter().sum();
|
|
||||||
// for size in &mut group.sizes {
|
|
||||||
// *size /= total;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// _ => {
|
|
||||||
// // Create new group
|
|
||||||
// let new_direction = if matches!(position, DropPosition::Above | DropPosition::Below) {
|
|
||||||
// SplitDirection::Vertical
|
|
||||||
// } else {
|
|
||||||
// SplitDirection::Horizontal
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let mut new_group = GroupNode {
|
|
||||||
// direction: new_direction,
|
|
||||||
// children: vec![],
|
|
||||||
// sizes: vec![],
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if matches!(position, DropPosition::Above | DropPosition::Left) {
|
|
||||||
// new_group.children.push(LayoutNode::Pane(dragged_pane.to_string()));
|
|
||||||
// new_group.children.push(LayoutNode::Pane(target_pane.to_string()));
|
|
||||||
// } else {
|
|
||||||
// new_group.children.push(LayoutNode::Pane(target_pane.to_string()));
|
|
||||||
// new_group.children.push(LayoutNode::Pane(dragged_pane.to_string()));
|
|
||||||
// }
|
|
||||||
// new_group.sizes = vec![0.5, 0.5];
|
|
||||||
|
|
||||||
// group.children[target_idx] = LayoutNode::Group(new_group);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else if path[0] < group.children.len() {
|
|
||||||
// self.insert_pane_at_target(
|
|
||||||
// &mut Some(group.children[path[0]].clone()),
|
|
||||||
// &path[1..],
|
|
||||||
// target_pane,
|
|
||||||
// dragged_pane,
|
|
||||||
// position,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn show_group(
|
|
||||||
// &mut self,
|
|
||||||
// ui: &mut egui::Ui,
|
|
||||||
// group: &GroupNode,
|
|
||||||
// path: &mut Vec<usize>,
|
|
||||||
// rect: egui::Rect,
|
|
||||||
// ) {
|
|
||||||
// let mut current_offset = if group.direction == SplitDirection::Horizontal {
|
|
||||||
// rect.left()
|
|
||||||
// } else {
|
|
||||||
// rect.top()
|
|
||||||
// };
|
|
||||||
|
|
||||||
// for (idx, (child, &size)) in group.children.iter().zip(group.sizes.iter()).enumerate() {
|
|
||||||
// path.push(idx);
|
|
||||||
|
|
||||||
// let child_size = if group.direction == SplitDirection::Horizontal {
|
|
||||||
// size * rect.width()
|
|
||||||
// } else {
|
|
||||||
// size * rect.height()
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let child_rect = if group.direction == SplitDirection::Horizontal {
|
|
||||||
// egui::Rect::from_min_size(
|
|
||||||
// egui::pos2(current_offset, rect.top()),
|
|
||||||
// egui::vec2(child_size, rect.height()),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// egui::Rect::from_min_size(
|
|
||||||
// egui::pos2(rect.left(), current_offset),
|
|
||||||
// egui::vec2(rect.width(), child_size),
|
|
||||||
// )
|
|
||||||
// };
|
|
||||||
|
|
||||||
// match child {
|
|
||||||
// LayoutNode::Pane(id) => {
|
|
||||||
// // let pane = self.panes.get_mut(id).unwrap();
|
|
||||||
// // if !pane.is_none(){
|
|
||||||
// self.show_pane(ui, id, child_rect, path.clone());
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// LayoutNode::Group(child_group) => {
|
|
||||||
// self.show_group(ui, child_group, path, child_rect);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// current_offset += child_size;
|
|
||||||
// path.pop();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn show_pane(
|
|
||||||
// &mut self,
|
|
||||||
// ui: &mut egui::Ui,
|
|
||||||
// id: &String,
|
|
||||||
// // pane: &mut Box<dyn Pane>,
|
|
||||||
// rect: egui::Rect,
|
|
||||||
// path: Vec<usize>,
|
|
||||||
// ) {
|
|
||||||
// let pane = self.panes.get_mut(id).unwrap();
|
|
||||||
// let response = ui.allocate_rect(rect, egui::Sense::drag());
|
|
||||||
|
|
||||||
// if response.dragged() {
|
|
||||||
// if self.drag_state.is_none() {
|
|
||||||
// self.drag_state = Some(DragState {
|
|
||||||
// dragged_pane: pane.name().to_string(),
|
|
||||||
// original_group_path: path.clone(),
|
|
||||||
// drag_started: true,
|
|
||||||
// drop_target: None,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Handle drop targeting
|
|
||||||
// if let Some(drag_state) = &mut self.drag_state {
|
|
||||||
// if drag_state.dragged_pane != pane.name() {
|
|
||||||
// let hover_pos: Option<egui::Pos2> = ui.input(|i| {i.pointer.hover_pos().clone()});
|
|
||||||
// if let Some(pos) = hover_pos {
|
|
||||||
// if rect.contains(pos) {
|
|
||||||
// let relative_pos = (pos - rect.min) / rect.size();
|
|
||||||
// let position = if relative_pos.y < 0.25 {
|
|
||||||
// DropPosition::Above
|
|
||||||
// } else if relative_pos.y > 0.75 {
|
|
||||||
// DropPosition::Below
|
|
||||||
// } else if relative_pos.x < 0.25 {
|
|
||||||
// DropPosition::Left
|
|
||||||
// } else if relative_pos.x > 0.75 {
|
|
||||||
// DropPosition::Right
|
|
||||||
// } else {
|
|
||||||
// DropPosition::Center
|
|
||||||
// };
|
|
||||||
|
|
||||||
// drag_state.drop_target = Some(DropTarget {
|
|
||||||
// target_pane: pane.name().to_string(),
|
|
||||||
// group_path: path,
|
|
||||||
// position,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Show the actual pane content
|
|
||||||
// let frame = egui::Frame::none()
|
|
||||||
// .fill(ui.style().visuals.window_fill)
|
|
||||||
// .stroke(ui.style().visuals.window_stroke)
|
|
||||||
// .inner_margin(egui::Margin::same(4.0));
|
|
||||||
|
|
||||||
// frame.show(ui, |ui| {
|
|
||||||
// ui.set_min_size(rect.size());
|
|
||||||
// pane.show(ui);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // fn is_valid_group
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl eframe::App for PaneManager {
|
|
||||||
// fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
|
||||||
// egui::TopBottomPanel::top("toolbar").show(ctx, |ui| {
|
|
||||||
// ui.horizontal(|ui| {
|
|
||||||
// ui.menu_button("File", |ui| {
|
|
||||||
// if ui.button("Save Layout").clicked() {
|
|
||||||
// self.save_layout();
|
|
||||||
// ui.close_menu();
|
|
||||||
// }
|
|
||||||
// if ui.button("Load Layout").clicked() {
|
|
||||||
// self.load_layout();
|
|
||||||
// ui.close_menu();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let any_down = ctx.input(|i| {i.pointer.any_down().clone()});
|
|
||||||
// if !any_down {// && drag_state.drag_started {
|
|
||||||
// self.handle_drop();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// egui::CentralPanel::default().show(ctx, |ui| {
|
|
||||||
|
|
||||||
// let mut root_group = if let LayoutNode::Group(c) = <std::option::Option<LayoutNode> as Clone>::clone(&self.layout.root).unwrap() {c} else { unreachable!() };
|
|
||||||
|
|
||||||
// // if let Some(LayoutNode::Group(root_group)) = &self.layout.root {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // // let root = LayoutNode::Group(&mut self.layout.root.unwrap());
|
|
||||||
|
|
||||||
// // // if LayoutNode::Group(root_group).unwrap()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// let mut path = Vec::new();
|
|
||||||
// self.show_group(ui, &root_group, &mut path, ui.available_rect_before_wrap());
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // Handle drag end
|
|
||||||
// // if let Some(drag_state) = &self.drag_state {
|
|
||||||
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
+147
-68
@@ -14,6 +14,7 @@ use egui::Align2;
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use egui::Stroke;
|
use egui::Stroke;
|
||||||
use egui::Ui;
|
use egui::Ui;
|
||||||
|
use crate::panes;
|
||||||
|
|
||||||
// Shader sources updated for 3D rendering with fixed-point positions
|
// Shader sources updated for 3D rendering with fixed-point positions
|
||||||
const VERTEX_SHADER: &str = r#"
|
const VERTEX_SHADER: &str = r#"
|
||||||
@@ -56,11 +57,13 @@ const FRAGMENT_SHADER: &str = r#"
|
|||||||
"#;
|
"#;
|
||||||
|
|
||||||
// Camera controller for 3D navigation
|
// Camera controller for 3D navigation
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
position: Vec3,
|
position: Vec3,
|
||||||
pub orientation: Quat,
|
pub orientation: Quat,
|
||||||
distance: f32,
|
distance: f32,
|
||||||
pub point_size_scale: f32,
|
pub point_size_scale: f32,
|
||||||
|
// last_pos: Option<Pos2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -71,6 +74,7 @@ impl Camera {
|
|||||||
orientation: Quat::IDENTITY,
|
orientation: Quat::IDENTITY,
|
||||||
distance: 5.0,
|
distance: 5.0,
|
||||||
point_size_scale: 0.1,
|
point_size_scale: 0.1,
|
||||||
|
// last_pos: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,12 +87,9 @@ impl Camera {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn update(&mut self, i: InputState) {
|
pub fn update(&mut self, i: InputState) {
|
||||||
// let response = {
|
|
||||||
// Mouse controls
|
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
|
|
||||||
// Right mouse button for rotation
|
if i.pointer.secondary_down() && !i.modifiers.shift {
|
||||||
if i.pointer.secondary_down() {
|
|
||||||
let delta = i.pointer.delta();
|
let delta = i.pointer.delta();
|
||||||
|
|
||||||
let rotation_speed = 0.01;
|
let rotation_speed = 0.01;
|
||||||
@@ -103,9 +104,31 @@ impl Camera {
|
|||||||
self.orientation = self.orientation.normalize();
|
self.orientation = self.orientation.normalize();
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
} // else if i.pointer.secondary_down() && i.modifiers.shift {
|
||||||
|
// let cur_pos = i.pointer.latest_pos();
|
||||||
// Scroll for zoom\
|
|
||||||
|
// if let Some(last_pos) = self.last_pos {
|
||||||
|
// let last_angle = f32::atan2(last_pos.y, last_pos.x);
|
||||||
|
// if let Some(cur_pos) = cur_pos {
|
||||||
|
// let cur_angle = f32::atan2(cur_pos.y, cur_pos.x);
|
||||||
|
|
||||||
|
// println!("{}",cur_angle - last_angle);
|
||||||
|
|
||||||
|
// let pitch_rotation = Quat::from_axis_angle(Vec3::X, 0.);
|
||||||
|
// let yaw_rotation = Quat::from_axis_angle(Vec3::Y, 0.);
|
||||||
|
// let roll_rotation = Quat::from_axis_angle(Vec3::Z,cur_angle-last_angle);
|
||||||
|
|
||||||
|
// self.orientation = self.orientation * pitch_rotation * yaw_rotation * roll_rotation;
|
||||||
|
// self.orientation = self.orientation.normalize();
|
||||||
|
|
||||||
|
// changed = true;
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// self.last_pos = cur_pos;
|
||||||
|
// }
|
||||||
|
|
||||||
let zoom_delta = i.smooth_scroll_delta.x + i.smooth_scroll_delta.y;
|
let zoom_delta = i.smooth_scroll_delta.x + i.smooth_scroll_delta.y;
|
||||||
if zoom_delta != 0. {
|
if zoom_delta != 0. {
|
||||||
if i.modifiers.shift {
|
if i.modifiers.shift {
|
||||||
@@ -119,7 +142,6 @@ impl Camera {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Middle mouse button for camera-plane panning
|
|
||||||
if i.pointer.primary_down() {
|
if i.pointer.primary_down() {
|
||||||
let delta = i.pointer.delta();
|
let delta = i.pointer.delta();
|
||||||
let pan_speed = self.distance * 0.001;
|
let pan_speed = self.distance * 0.001;
|
||||||
@@ -135,7 +157,6 @@ impl Camera {
|
|||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -194,18 +215,35 @@ struct PlyHeader {
|
|||||||
// color: Color32,
|
// color: Color32,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct PointRenderer {
|
pub struct PointRenderer {
|
||||||
gl: Arc<glow::Context>,
|
pub gl: Option<Arc<glow::Context>>,
|
||||||
program: glow::Program,
|
program: Option<glow::Program>,
|
||||||
vao: glow::VertexArray,
|
vao: Option<glow::VertexArray>,
|
||||||
vbo: glow::Buffer,
|
vbo: Option<glow::Buffer>,
|
||||||
points: Vec<i32>,
|
points: Option<Vec<i32>>,
|
||||||
// capacity: usize,
|
// capacity: usize,
|
||||||
pub camera: Camera,
|
pub camera: Option<Camera>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl Defalt for PointRenderer {
|
||||||
|
// fn default() -> Self {
|
||||||
|
// Self {
|
||||||
|
// gl: Option<Arc<glow::Context>>,
|
||||||
|
// program: Option<glow::Program>,
|
||||||
|
// vao: Option<glow::VertexArray>,
|
||||||
|
// vbo: Option<glow::Buffer>,
|
||||||
|
// points: Option<Vec<i32>>,
|
||||||
|
// // capacity: usize,
|
||||||
|
// camera: Option<Camera>,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl PointRenderer {
|
impl PointRenderer {
|
||||||
pub fn new(gl: Option<Arc<glow::Context>>, initial_capacity: usize) -> Self {
|
pub fn init(&mut self, gl: Option<Arc<glow::Context>>, initial_capacity: usize) {
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
|
|
||||||
let gl = gl.unwrap();
|
let gl = gl.unwrap();
|
||||||
@@ -258,24 +296,22 @@ impl PointRenderer {
|
|||||||
vbo
|
vbo
|
||||||
};
|
};
|
||||||
|
|
||||||
PointRenderer {
|
self.gl = Some(gl);
|
||||||
gl,
|
self.program = Some(program);
|
||||||
program,
|
self.vao = Some(vao);
|
||||||
vao,
|
self.vbo = Some(vbo);
|
||||||
vbo,
|
self.points = Some(Vec::with_capacity(initial_capacity * 7));
|
||||||
points: Vec::with_capacity(initial_capacity * 7),
|
|
||||||
// capacity: initial_capacity,
|
// capacity: initial_capacity,
|
||||||
camera: Camera::new(),
|
self.camera = Some(Camera::new());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_point(&mut self, x: i32, y: i32, z: i32, color: Color32) {
|
pub fn add_point(&mut self, x: i32, y: i32, z: i32, color: Color32) {
|
||||||
let [r, g, b, a] = color.to_array();
|
let [r, g, b, a] = color.to_array();
|
||||||
self.points.extend_from_slice(&[x, y, z, r as i32, g as i32, b as i32, a as i32]);
|
self.points.as_mut().as_mut().expect("Not Initialised").extend_from_slice(&[x, y, z, r as i32, g as i32, b as i32, a as i32]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.points.clear();
|
self.points.as_mut().as_mut().expect("Not Initialised").clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self, rect: Rect, input_state: Option<InputState>) {
|
pub fn render(&mut self, rect: Rect, input_state: Option<InputState>) {
|
||||||
@@ -283,55 +319,55 @@ impl PointRenderer {
|
|||||||
|
|
||||||
// Update camera
|
// Update camera
|
||||||
if let Some(i) = input_state{
|
if let Some(i) = input_state{
|
||||||
self.camera.update(i);
|
self.camera.as_mut().expect("Not Initialised").update(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
self.gl.use_program(Some(self.program));
|
self.gl.as_mut().expect("Not Initialised").use_program(self.program);
|
||||||
|
|
||||||
// Set up view-projection matrix
|
// Set up view-projection matrix
|
||||||
let aspect = rect.width() / rect.height();
|
let aspect = rect.width() / rect.height();
|
||||||
let projection = Mat4::perspective_rh(45.0f32.to_radians(), aspect, 0.1, 1000.0);
|
let projection = Mat4::perspective_rh(45.0f32.to_radians(), aspect, 0.1, 1000.0);
|
||||||
let view = self.camera.get_view_matrix();
|
let view = self.camera.as_mut().expect("Not Initialised").get_view_matrix();
|
||||||
let view_projection = projection * view;
|
let view_projection = projection * view;
|
||||||
|
|
||||||
let location = self.gl.get_uniform_location(self.program, "u_view_projection")
|
let location = self.gl.as_mut().expect("Not Initialised").get_uniform_location(*self.program.as_mut().expect("Not Initialised"), "u_view_projection")
|
||||||
.expect("Cannot get uniform location");
|
.expect("Cannot get uniform location");
|
||||||
self.gl.uniform_matrix_4_f32_slice(Some(&location), false, &view_projection.to_cols_array());
|
self.gl.as_mut().expect("Not Initialised").uniform_matrix_4_f32_slice(Some(&location), false, &view_projection.to_cols_array());
|
||||||
|
|
||||||
// Set position scale factor (converts uint positions to world space)
|
// Set position scale factor (converts uint positions to world space)
|
||||||
let scale_location = self.gl.get_uniform_location(self.program, "u_position_scale")
|
let scale_location = self.gl.as_mut().expect("Not Initialised").get_uniform_location(*self.program.as_mut().expect("Not Initialised"), "u_position_scale")
|
||||||
.expect("Cannot get scale uniform location");
|
.expect("Cannot get scale uniform location");
|
||||||
self.gl.uniform_1_f32(Some(&scale_location), 0.001); // Adjust this value to scale your point cloud
|
self.gl.as_mut().expect("Not Initialised").uniform_1_f32(Some(&scale_location), 0.001); // Adjust this value to scale your point cloud
|
||||||
|
|
||||||
let point_size_location = self.gl.get_uniform_location(self.program, "u_point_size_scale")
|
let point_size_location = self.gl.as_mut().expect("Not Initialised").get_uniform_location(*self.program.as_mut().expect("Not Initialised"), "u_point_size_scale")
|
||||||
.expect("Cannot get point size scale location");
|
.expect("Cannot get point size scale location");
|
||||||
self.gl.uniform_1_f32(Some(&point_size_location), self.camera.point_size_scale);
|
self.gl.as_mut().expect("Not Initialised").uniform_1_f32(Some(&point_size_location), self.camera.as_mut().expect("Not Initialised").point_size_scale);
|
||||||
|
|
||||||
self.gl.bind_vertex_array(Some(self.vao));
|
self.gl.as_mut().expect("Not Initialised").bind_vertex_array(self.vao);
|
||||||
self.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vbo));
|
self.gl.as_mut().expect("Not Initialised").bind_buffer(glow::ARRAY_BUFFER, Some(*self.vbo.as_mut().expect("Not Initialised")));
|
||||||
|
|
||||||
self.gl.buffer_sub_data_u8_slice(
|
self.gl.as_mut().expect("Not Initialised").buffer_sub_data_u8_slice(
|
||||||
glow::ARRAY_BUFFER,
|
glow::ARRAY_BUFFER,
|
||||||
0,
|
0,
|
||||||
bytemuck::cast_slice(&self.points),
|
bytemuck::cast_slice(&self.points.as_mut().expect("Not Initialised")),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.gl.enable(glow::PROGRAM_POINT_SIZE);
|
self.gl.as_mut().expect("Not Initialised").enable(glow::PROGRAM_POINT_SIZE);
|
||||||
self.gl.enable(glow::DEPTH_TEST);
|
self.gl.as_mut().expect("Not Initialised").enable(glow::DEPTH_TEST);
|
||||||
|
|
||||||
|
|
||||||
self.gl.clear_depth_f32(1.0);
|
self.gl.as_mut().expect("Not Initialised").clear_depth_f32(1.0);
|
||||||
self.gl.depth_func(glow::LESS);
|
self.gl.as_mut().expect("Not Initialised").depth_func(glow::LESS);
|
||||||
self.gl.depth_mask(true);
|
self.gl.as_mut().expect("Not Initialised").depth_mask(true);
|
||||||
|
|
||||||
// self.gl.clear_color(0.3, 0.3, 0.3, 1.0);
|
// self.gl.clear_color(0.3, 0.3, 0.3, 1.0);
|
||||||
self.gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
|
self.gl.as_mut().expect("Not Initialised").clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
self.gl.draw_arrays(glow::POINTS, 0, (self.points.len() / 7) as i32);
|
self.gl.as_mut().expect("Not Initialised").draw_arrays(glow::POINTS, 0, (self.points.as_mut().as_mut().expect("Not Initialised").len() / 7) as i32);
|
||||||
|
|
||||||
self.gl.disable(glow::DEPTH_TEST);
|
self.gl.as_mut().expect("Not Initialised").disable(glow::DEPTH_TEST);
|
||||||
self.gl.disable(glow::PROGRAM_POINT_SIZE);
|
self.gl.as_mut().expect("Not Initialised").disable(glow::PROGRAM_POINT_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +394,7 @@ impl PointRenderer {
|
|||||||
self.clear();
|
self.clear();
|
||||||
|
|
||||||
// Reserve capacity
|
// Reserve capacity
|
||||||
self.points.reserve(header.vertex_count * 7);
|
self.points.as_mut().as_mut().expect("Not Initialised").reserve(header.vertex_count * 7);
|
||||||
|
|
||||||
// Parse vertices based on format
|
// Parse vertices based on format
|
||||||
if header.is_binary {
|
if header.is_binary {
|
||||||
@@ -457,17 +493,48 @@ impl Drop for PointRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
pub struct PointRendererPane {
|
pub struct PointRendererPane {
|
||||||
|
#[serde(skip)]
|
||||||
renderer: Arc<Mutex<PointRenderer>>,
|
renderer: Arc<Mutex<PointRenderer>>,
|
||||||
|
#[serde(skip)]
|
||||||
points: Vec<(i32, i32, i32, Color32)>,
|
points: Vec<(i32, i32, i32, Color32)>,
|
||||||
|
#[serde(skip)]
|
||||||
file_dialog_open: bool,
|
file_dialog_open: bool,
|
||||||
|
#[serde(skip)]
|
||||||
cur_path: String,
|
cur_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl Default for PointRenderer {
|
||||||
|
// fn default() -> Self {
|
||||||
|
// Self {}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[typetag::serde]
|
||||||
impl Pane for PointRendererPane {
|
impl Pane for PointRendererPane {
|
||||||
fn new(cc: &eframe::CreationContext<'_>) -> PaneState where Self: Sized {
|
fn new() -> PaneState where Self: Sized {
|
||||||
|
let mut renderer = PointRenderer::default();
|
||||||
let mut s = Self {
|
let mut s = Self {
|
||||||
renderer: Arc::new(Mutex::new(PointRenderer::new(cc.gl.clone(), 1_000_000))),
|
renderer: Arc::new(Mutex::new(renderer)),
|
||||||
points: Vec::new(),
|
points: Vec::new(),
|
||||||
file_dialog_open: false,
|
file_dialog_open: false,
|
||||||
cur_path: "./".to_string(),
|
cur_path: "./".to_string(),
|
||||||
@@ -478,14 +545,21 @@ impl Pane for PointRendererPane {
|
|||||||
pane: Box::new(s),
|
pane: Box::new(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn init(&mut self, pcc: &panes::PsudoCreationContext){
|
||||||
|
self.renderer.lock().expect("Renderer Not Initialized").init(pcc.gl.clone(), 1_000_000);
|
||||||
|
}
|
||||||
fn name(&mut self) -> &str {"Point Cloud"}
|
fn name(&mut self) -> &str {"Point Cloud"}
|
||||||
fn render(&mut self, ui: &mut Ui){
|
fn render(&mut self, ui: &mut Ui){
|
||||||
|
|
||||||
let max_rect = ui.max_rect();
|
let max_rect = ui.max_rect();
|
||||||
|
|
||||||
let renderer = self.renderer.clone();
|
let renderer = self.renderer.clone();
|
||||||
|
if renderer.lock().expect("Renderer Not Initialized").gl.is_none() {
|
||||||
|
return;
|
||||||
|
// renderer.lock().expect("Renderer Not Initialized").init(ui.ctx()., 1_000_000);
|
||||||
|
}
|
||||||
renderer.lock().expect("Renderer Not Initialized").clear();
|
renderer.lock().expect("Renderer Not Initialized").clear();
|
||||||
|
|
||||||
|
|
||||||
if self.file_dialog_open {
|
if self.file_dialog_open {
|
||||||
egui::Window::new("Load PLY File")
|
egui::Window::new("Load PLY File")
|
||||||
.show(ui.ctx(), |ui| {
|
.show(ui.ctx(), |ui| {
|
||||||
@@ -557,7 +631,7 @@ impl Pane for PointRendererPane {
|
|||||||
renderer.lock().expect("Renderer Not Initialized").add_point(x, y, z, color);
|
renderer.lock().expect("Renderer Not Initialized").add_point(x, y, z, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
let o = renderer.lock().expect("Renderer Not Initialized").camera.orientation.clone();
|
let o = <std::option::Option<Camera> as Clone>::clone(&renderer.lock().expect("Renderer Not Initialized").camera).unwrap().orientation.clone();
|
||||||
|
|
||||||
let cb = egui_glow::CallbackFn::new(move |_info, _painter| {
|
let cb = egui_glow::CallbackFn::new(move |_info, _painter| {
|
||||||
renderer.lock().expect("Renderer Not Initialized").render(max_rect, input_state.clone());
|
renderer.lock().expect("Renderer Not Initialized").render(max_rect, input_state.clone());
|
||||||
@@ -570,28 +644,33 @@ impl Pane for PointRendererPane {
|
|||||||
|
|
||||||
ui.painter().add(callback);
|
ui.painter().add(callback);
|
||||||
|
|
||||||
let pos1 = o.inverse()*glam::Vec3::X;
|
|
||||||
let pos2 = o.inverse()*glam::Vec3::Y;
|
|
||||||
let pos3 = o.inverse()*glam::Vec3::Z;
|
|
||||||
|
|
||||||
let line_length:f32 = 20.;
|
let line_length:f32 = 20.;
|
||||||
|
|
||||||
ui.painter().line_segment([rect.center(), rect.center() + egui::Vec2{ x: line_length*pos1.x, y: -line_length*pos1.y,}], Stroke {
|
// if let Some(input_state) = input_state {
|
||||||
width: 1.5,
|
// if input_state.pointer.any_down() {
|
||||||
color: Color32::RED,
|
|
||||||
});
|
let pos1 = o.inverse()*glam::Vec3::X;
|
||||||
|
let pos2 = o.inverse()*glam::Vec3::Y;
|
||||||
|
let pos3 = o.inverse()*glam::Vec3::Z;
|
||||||
|
|
||||||
|
ui.painter().line_segment([rect.center(), rect.center() + egui::Vec2{ x: line_length*pos1.x, y: -line_length*pos1.y,}], Stroke {
|
||||||
|
width: 1.5,
|
||||||
|
color: Color32::RED,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
ui.painter().line_segment([rect.center(), rect.center() + egui::Vec2{ x: line_length*pos2.x, y: -line_length*pos2.y,}], Stroke {
|
ui.painter().line_segment([rect.center(), rect.center() + egui::Vec2{ x: line_length*pos2.x, y: -line_length*pos2.y,}], Stroke {
|
||||||
width: 1.5,
|
width: 1.5,
|
||||||
color: Color32::BLUE,
|
color: Color32::BLUE,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
ui.painter().line_segment([rect.center(), rect.center() + egui::Vec2{ x: line_length*pos3.x, y: -line_length*pos3.y,}], Stroke {
|
ui.painter().line_segment([rect.center(), rect.center() + egui::Vec2{ x: line_length*pos3.x, y: -line_length*pos3.y,}], Stroke {
|
||||||
width: 1.5,
|
width: 1.5,
|
||||||
color: Color32::GREEN,
|
color: Color32::GREEN,
|
||||||
});
|
});
|
||||||
|
// }}
|
||||||
|
|
||||||
let end_time = Instant::now();
|
let end_time = Instant::now();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user