working load-from-file. fixed struct-asset issue with childless root nodes. selection swapper functional (for structures, grids not working(??))
REMAINING FOR MVP: edit-node-data (REQUIRED), gizmos (arguable)
This commit is contained in:
parent
41b673753e
commit
6c289f30f9
|
@ -1,5 +1,5 @@
|
|||
version 1
|
||||
test
|
||||
head|none
|
||||
||
|
||||
element|torso
|
||||
position|0|0|0
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::{
|
||||
app::{Startup, Update}, asset::{AssetServer, Assets, Handle}, ecs::{
|
||||
entity::Entity, event::EventWriter, query::With, system::{Commands, Query, Res, ResMut, Resource}
|
||||
}, hierarchy::BuildChildren, math::Vec3, pbr::{PointLight, PointLightBundle}, prelude::{default, SpatialBundle}, render::{camera::Camera, color::Color, view::Visibility}, transform::{components::{GlobalTransform, Transform}, TransformBundle}, utils::{hashbrown::hash_map::Entry, HashMap}, window::{PrimaryWindow, Window, WindowResolution}
|
||||
entity::Entity, event::EventWriter, query::With, system::{Commands, Query, Res, ResMut}
|
||||
}, math::Vec3, pbr::{PointLight, PointLightBundle}, prelude::{default, Resource, SpatialBundle}, render::{camera::Camera, color::Color, view::Visibility}, transform::components::{GlobalTransform, Transform}, utils::{hashbrown::hash_map::Entry, HashMap}, window::{PrimaryWindow, Window, WindowResolution}
|
||||
};
|
||||
use bevy_egui::{
|
||||
egui::{self, color_picker, epaint::Hsva, Id, Pos2, Rect, ScrollArea},
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||
vvedit::s_editor_bevy_input_shim::keybind_codes::REMOVE_VOXEL,
|
||||
vvlib::{
|
||||
s_inputs::InputRegister, s_intersections::octtree_ray_overlap, s_obb::OBB,
|
||||
s_oct_asset::OctAssetMarker, s_structure_asset::{StructureAsset, StructureComponent, StructureUpdateMessage, StructureUpdateType},
|
||||
s_oct_asset::OctAssetMarker, s_structure_asset::{StructureAsset, StructureUpdateMessage, StructureUpdateType},
|
||||
},
|
||||
};
|
||||
use crate::{
|
||||
|
@ -29,11 +29,15 @@ use super::{
|
|||
|
||||
use std::fmt::Write;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GridEditData {
|
||||
pub path: String,
|
||||
pub id: Handle<OctTreeAsset>,
|
||||
pub edit_entity: Entity, //which instance of this structure is representing the one we can edit in the structure editor. other instances will exist which will be tricky (seperate store?)
|
||||
pub has_changed_since_last_save: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StructureEditData {
|
||||
pub path: String,
|
||||
pub id: Handle<StructureAsset>,
|
||||
|
@ -48,16 +52,13 @@ pub struct EditWindowUIState {
|
|||
pub structures: Vec<StructureEditData>,
|
||||
pub egui: EditWindowEguiState,
|
||||
pub popup: PopupWindowMode,
|
||||
//pub selected_structure_element: String,
|
||||
//pub selected_structure: String,
|
||||
//pub selected_grid: String,
|
||||
pub display_state: DisplayState,
|
||||
pub display_root: Entity,
|
||||
pub selection: Selection,
|
||||
pub struct_element_selections: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, PartialEq)]
|
||||
#[derive(Default, Clone, PartialEq, Debug)]
|
||||
pub enum Selection {
|
||||
#[default]
|
||||
None,
|
||||
|
@ -212,6 +213,7 @@ impl EditWindowUIState {
|
|||
self.grids.push(GridEditData {
|
||||
path: path.clone(),
|
||||
id,
|
||||
edit_entity: Entity::PLACEHOLDER, // BAD BAD BAD TODO: Finish this
|
||||
has_changed_since_last_save: has_changed,
|
||||
});
|
||||
return true;
|
||||
|
@ -242,14 +244,8 @@ pub fn register_edit_ui(
|
|||
pub fn startup_system_edit_ui(
|
||||
mut commands: Commands,
|
||||
mut shared_ui_state: ResMut<EditWindowUIState>,
|
||||
asset_server: ResMut<AssetServer>,
|
||||
mut event_writer: EventWriter<StructureUpdateMessage>,
|
||||
) {
|
||||
spawn_camera(&mut commands);
|
||||
/*
|
||||
let str = "test.vvs";
|
||||
let handle = asset_server.load::<StructureAsset>(str);
|
||||
*/
|
||||
let display_parent = commands
|
||||
.spawn(SpatialBundle {
|
||||
visibility: Visibility::Visible,
|
||||
|
@ -258,27 +254,6 @@ pub fn startup_system_edit_ui(
|
|||
})
|
||||
.id();
|
||||
shared_ui_state.display_root = display_parent;
|
||||
/*
|
||||
let id = commands.spawn((SpatialBundle {
|
||||
visibility: Visibility::Visible,
|
||||
..Default::default()
|
||||
}, StructureComponent {
|
||||
asset: handle.clone(),
|
||||
nodes: Default::default(),
|
||||
})).id();
|
||||
let data = StructureEditData {
|
||||
path: str.into(),
|
||||
id: handle.clone(),
|
||||
has_changed_since_last_save: false,
|
||||
edit_entity: id.clone(),
|
||||
};
|
||||
shared_ui_state.structures.push(data);
|
||||
commands.entity(display_parent).add_child(id.clone());
|
||||
event_writer.send(StructureUpdateMessage {
|
||||
update_type: StructureUpdateType::Rebuild,
|
||||
entity: id,
|
||||
});
|
||||
*/
|
||||
let light_transform = Transform::from_xyz(4f32, 4f32, 4f32).looking_at(Vec3::ZERO, Vec3::Y);
|
||||
|
||||
commands.spawn(PointLightBundle {
|
||||
|
@ -449,6 +424,7 @@ pub fn edit_window_ui(
|
|||
mut pairs: ResMut<MeshingOctTreePairs>,
|
||||
windows: Query<Entity, With<Window>>,
|
||||
window: Query<&Window>,
|
||||
mut visibility: Query<&mut Visibility>,
|
||||
mut asset_server: ResMut<AssetServer>,
|
||||
mut event_writer: EventWriter<StructureUpdateMessage>,
|
||||
mut commands: Commands,
|
||||
|
@ -606,11 +582,6 @@ pub fn edit_window_ui(
|
|||
}
|
||||
let mut selection: Selection = shared_ui_state.selection.clone();
|
||||
ui.collapsing("grid assets", |ui| {
|
||||
if !shared_ui_state.selection.is_none() {
|
||||
if ui.button("Deselect Asset").clicked() {
|
||||
shared_ui_state.selection = Selection::None;
|
||||
}
|
||||
}
|
||||
for grid in &shared_ui_state.grids {
|
||||
ui.radio_value(
|
||||
&mut selection,
|
||||
|
@ -620,21 +591,17 @@ pub fn edit_window_ui(
|
|||
}
|
||||
});
|
||||
ui.collapsing("structure assets", |ui| {
|
||||
if !shared_ui_state.selection.is_none() {
|
||||
if ui.button("Deselect Asset").clicked() {
|
||||
shared_ui_state.selection = Selection::None;
|
||||
}
|
||||
}
|
||||
for structure in &shared_ui_state.structures {
|
||||
ui.radio_value(
|
||||
&mut selection,
|
||||
Selection::Grid(structure.path.to_string()),
|
||||
Selection::Structure(structure.path.to_string()),
|
||||
structure.path.to_string().as_str(),
|
||||
);
|
||||
}
|
||||
});
|
||||
if selection != shared_ui_state.selection {
|
||||
shared_ui_state.selection = selection;
|
||||
update_selection(&mut shared_ui_state, &mut visibility);
|
||||
}
|
||||
let mut selected_structure = false;
|
||||
let mut selection = Option::<StringTree>::None;
|
||||
|
|
|
@ -9,7 +9,7 @@ use bevy::{
|
|||
ecs::{entity::Entity, event::EventWriter, system::ResMut},
|
||||
hierarchy::BuildChildren,
|
||||
math::{Quat, Vec3},
|
||||
prelude::{Commands, SpatialBundle},
|
||||
prelude::{Commands, Query, SpatialBundle},
|
||||
render::{color::Color, view::Visibility},
|
||||
utils::hashbrown::hash_map::Entry,
|
||||
};
|
||||
|
@ -27,7 +27,7 @@ use crate::{
|
|||
vvedit::s_editor_ui::{GridEditData, Selection, StructureEditData},
|
||||
vvlib::{
|
||||
s_identifier_validation::{self, is_valid},
|
||||
s_oct_asset::OctTreeAsset,
|
||||
s_oct_asset::{OctAssetMarker, OctTreeAsset},
|
||||
s_octtree::OctTree,
|
||||
s_structure_asset::{
|
||||
StructureAsset, StructureComponent, StructureUpdateMessage, StructureUpdateType,
|
||||
|
@ -338,9 +338,9 @@ pub fn show_popup(
|
|||
edit_entity: id.clone(),
|
||||
};
|
||||
state.structures.push(data);
|
||||
commands.entity(state.display_root).add_child(id);
|
||||
commands.entity(state.display_root).add_child(id.clone());
|
||||
event_writer.send(StructureUpdateMessage {
|
||||
update_type: StructureUpdateType::Rebuild,
|
||||
update_type: StructureUpdateType::Build,
|
||||
entity: id,
|
||||
});
|
||||
}
|
||||
|
@ -348,9 +348,22 @@ pub fn show_popup(
|
|||
}
|
||||
Extension::Grid => {
|
||||
let handle = asset_server.load::<OctTreeAsset>(path_pre.clone());
|
||||
let id = commands
|
||||
.spawn((
|
||||
SpatialBundle {
|
||||
visibility: Visibility::Visible,
|
||||
..Default::default()
|
||||
},
|
||||
OctAssetMarker {
|
||||
oct_handle: handle.clone(),
|
||||
},
|
||||
))
|
||||
.id();
|
||||
commands.entity(state.display_root).add_child(id.clone());
|
||||
let data = GridEditData {
|
||||
path: path_pre,
|
||||
id: handle,
|
||||
edit_entity: id.clone(),
|
||||
has_changed_since_last_save: false,
|
||||
};
|
||||
let mut loaded_already = false;
|
||||
|
@ -451,13 +464,12 @@ pub fn show_popup(
|
|||
// add structure
|
||||
let handle = asset_server.add::<StructureAsset>(Default::default());
|
||||
let handleclone = handle.clone();
|
||||
let data = StructureEditData {
|
||||
let mut data = StructureEditData {
|
||||
path: final_path,
|
||||
id: handle,
|
||||
has_changed_since_last_save: false,
|
||||
edit_entity: Entity::PLACEHOLDER, //BAD BAD BAD
|
||||
};
|
||||
state.structures.push(data);
|
||||
state_change = PopupStateChange::Close;
|
||||
|
||||
let id = commands
|
||||
|
@ -472,11 +484,13 @@ pub fn show_popup(
|
|||
},
|
||||
))
|
||||
.id();
|
||||
commands.entity(state.display_root).add_child(id);
|
||||
commands.entity(state.display_root).add_child(id.clone());
|
||||
event_writer.send(StructureUpdateMessage {
|
||||
update_type: StructureUpdateType::Rebuild,
|
||||
entity: id,
|
||||
update_type: StructureUpdateType::Build,
|
||||
entity: id.clone(),
|
||||
});
|
||||
data.edit_entity = id;
|
||||
state.structures.push(data);
|
||||
} else {
|
||||
// add grid
|
||||
let handle = asset_server.add::<OctTreeAsset>(OctTreeAsset {
|
||||
|
@ -487,14 +501,26 @@ pub fn show_popup(
|
|||
handle: None,
|
||||
task: None,
|
||||
});
|
||||
let id = commands
|
||||
.spawn((
|
||||
SpatialBundle {
|
||||
visibility: Visibility::Visible,
|
||||
..Default::default()
|
||||
},
|
||||
OctAssetMarker {
|
||||
oct_handle: handle.clone(),
|
||||
},
|
||||
))
|
||||
.id();
|
||||
commands.entity(state.display_root).add_child(id.clone());
|
||||
let data = GridEditData {
|
||||
path: final_path,
|
||||
id: handle,
|
||||
edit_entity: id,
|
||||
has_changed_since_last_save: true,
|
||||
};
|
||||
state.grids.push(data);
|
||||
state_change = PopupStateChange::Close;
|
||||
// SPAWN ENTITY?
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -737,4 +763,54 @@ pub fn editable_quat(ui: &mut egui::Ui, value: &mut Quat, should_reshape: &mut b
|
|||
}
|
||||
}
|
||||
|
||||
//pub fn set_visibility
|
||||
pub fn update_selection(
|
||||
shared_ui_state: &mut ResMut<EditWindowUIState>,
|
||||
visibility: &mut Query<&mut Visibility>,
|
||||
) {
|
||||
let mut set_visible = Option::<Entity>::None;
|
||||
if let Selection::Grid(some) = &shared_ui_state.selection {
|
||||
for grid in &shared_ui_state.grids {
|
||||
if &grid.path == some {
|
||||
set_visible = Some(grid.edit_entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if let Selection::Structure(some) = &shared_ui_state.selection {
|
||||
for structure in &shared_ui_state.structures {
|
||||
if &structure.path == some {
|
||||
set_visible = Some(structure.edit_entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for each_grid in &shared_ui_state.grids.clone() {
|
||||
let ent = each_grid.edit_entity;
|
||||
let each = visibility.get_mut(ent);
|
||||
if let Ok(mut each) = each {
|
||||
if let Some(set_visible) = set_visible.clone() {
|
||||
if ent == set_visible {
|
||||
*each = Visibility::Visible;
|
||||
} else {
|
||||
*each = Visibility::Hidden;
|
||||
}
|
||||
} else {
|
||||
*each = Visibility::Hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
for each_structure in &shared_ui_state.structures.clone() {
|
||||
let ent = each_structure.edit_entity;
|
||||
let each = visibility.get_mut(ent);
|
||||
if let Ok(mut each) = each {
|
||||
if let Some(set_visible) = set_visible.clone() {
|
||||
if ent == set_visible {
|
||||
*each = Visibility::Visible;
|
||||
} else {
|
||||
*each = Visibility::Hidden;
|
||||
}
|
||||
} else {
|
||||
*each = Visibility::Hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
what its like to load a file
|
||||
default structure is empty
|
||||
no meshes loaded
|
||||
load a structure: display structure is updated. load all meshes in the structure.
|
||||
load a mesh: add a mesh node in the structure at root with name of mesh
|
||||
|
||||
DONE:
|
||||
want a discovery-list-display of all known assets - scan assets folder
|
||||
Keep track of if structure or meshes have changed, when they changed offer to save if loading a new structure or closing program (meshes will stay loaded unchanged until close, loading a new structure erases current structure (temp?))
|
|
@ -1,4 +1,7 @@
|
|||
pub fn is_valid<S: Into<String>>(text: S) -> bool {
|
||||
let text: String = text.into();
|
||||
!(text.contains("|") & text.contains(char::is_whitespace) & text.contains(","))
|
||||
!(text.contains("|")
|
||||
& text.contains(char::is_whitespace)
|
||||
& text.contains(",")
|
||||
& (text.to_lowercase() != "none"))
|
||||
}
|
||||
|
|
|
@ -430,7 +430,9 @@ pub mod serialization {
|
|||
}
|
||||
while let Some(each) = tokens.next() {
|
||||
let each = each.trim().to_string();
|
||||
result.layout.add_child(&each, &parent);
|
||||
if each.to_lowercase() != "none" {
|
||||
result.layout.add_child(&each, &parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -685,6 +687,8 @@ pub mod serialization {
|
|||
if children.is_empty() {
|
||||
*data += NEWLINE;
|
||||
*data += element.as_str();
|
||||
*data += "|";
|
||||
*data += "none";
|
||||
return;
|
||||
}
|
||||
*data += NEWLINE;
|
||||
|
|
Loading…
Reference in a new issue