testing
This commit is contained in:
parent
7e91f93fe0
commit
2f8afb8403
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -8,6 +8,7 @@
|
|||
"./Cargo.toml",
|
||||
"./Cargo.toml",
|
||||
"./Cargo.toml",
|
||||
"./Cargo.toml",
|
||||
"./Cargo.toml"
|
||||
],
|
||||
}
|
|
@ -10,6 +10,7 @@ mod s_orbit_camera;
|
|||
pub mod s_string_tree;
|
||||
pub mod s_ui_details;
|
||||
|
||||
|
||||
pub fn setup(app: &mut App) -> &mut App {
|
||||
app.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
|
|
|
@ -69,7 +69,7 @@ impl Default for EditWindowUIState {
|
|||
pub enum PopupWindowMode {
|
||||
#[default]
|
||||
None,
|
||||
StructureElement(String),
|
||||
EditStructureElement(String, String), //rename from and to, otherwise second string is unused
|
||||
}
|
||||
impl PopupWindowMode {
|
||||
pub fn is_none(&self) -> bool {
|
||||
|
@ -394,7 +394,7 @@ pub fn edit_window_ui(
|
|||
for window_entity in &windows {
|
||||
let ctx = contexts.ctx_for_window_mut(window_entity);
|
||||
let pos = ctx.memory(|memory| {
|
||||
if let PopupWindowMode::StructureElement(_) = shared_ui_state.popup {
|
||||
if let PopupWindowMode::EditStructureElement(_, _) = shared_ui_state.popup {
|
||||
memory.area_rect(shared_ui_state.egui.popup_identifier.unwrap())
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -46,6 +46,33 @@ impl StringTree {
|
|||
pub fn new() -> Self {
|
||||
StringTree { root: Vec::new() }
|
||||
}
|
||||
pub fn rename(&mut self, subject: &String, new_name: &String) -> bool {
|
||||
for each in &mut self.root {
|
||||
if Self::recursive_search_rename(each, subject, new_name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
fn recursive_search_rename(
|
||||
element: &mut StringTreeElement,
|
||||
subject: &String,
|
||||
new_name: &String,
|
||||
) -> bool {
|
||||
if let StringTreeElement::Element(title, children) = element {
|
||||
if title == subject {
|
||||
*title = new_name.clone();
|
||||
return true;
|
||||
} else {
|
||||
for each in children.as_mut() {
|
||||
if Self::recursive_search_rename(each, subject, new_name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
pub fn add_root_level(&mut self, element: &String) -> bool {
|
||||
for each in &self.root {
|
||||
if Self::check_present(each, element) {
|
||||
|
|
|
@ -8,6 +8,8 @@ use bevy_egui::{
|
|||
EguiContexts,
|
||||
};
|
||||
|
||||
use crate::vvlib::s_identifier_validation;
|
||||
|
||||
use super::{
|
||||
s_editor_ui::{EditWindowUIState, PopupWindowMode},
|
||||
s_string_tree::StringTreeElement,
|
||||
|
@ -60,9 +62,10 @@ pub fn round_trip_color() {
|
|||
pub fn show_popup(state: &mut EditWindowUIState, contexts: &mut EguiContexts) {
|
||||
let mut change_state = None;
|
||||
let mut reparent = None;
|
||||
match &state.popup {
|
||||
let mut rename_complete = false;
|
||||
match &mut state.popup {
|
||||
PopupWindowMode::None => return,
|
||||
PopupWindowMode::StructureElement(name) => {
|
||||
PopupWindowMode::EditStructureElement(name, rename) => {
|
||||
//formatting comment
|
||||
let response = egui::Window::new("edit structure element ".to_owned() + &name.clone())
|
||||
.id(state.egui.popup_identifier.unwrap());
|
||||
|
@ -70,6 +73,19 @@ pub fn show_popup(state: &mut EditWindowUIState, contexts: &mut EguiContexts) {
|
|||
//formatting comment
|
||||
let cur = name.clone();
|
||||
ui.label("what do you want to do with ".to_owned() + &name + "?");
|
||||
ui.horizontal(|ui| {
|
||||
//.
|
||||
ui.label("rename element: ");
|
||||
let mut rename_string = rename.clone();
|
||||
ui.text_edit_singleline(&mut rename_string);
|
||||
if s_identifier_validation::is_valid(rename_string.clone()) {
|
||||
*rename = rename_string;
|
||||
}
|
||||
if ui.button("Confirm and change name").clicked() {
|
||||
//.
|
||||
rename_complete = true;
|
||||
}
|
||||
});
|
||||
enum Tasks {
|
||||
MoveElement,
|
||||
RemoveElement,
|
||||
|
@ -113,6 +129,16 @@ pub fn show_popup(state: &mut EditWindowUIState, contexts: &mut EguiContexts) {
|
|||
} else {
|
||||
state.structure.deparent(&cur);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if rename_complete {
|
||||
if let PopupWindowMode::EditStructureElement(old, new) = &state.popup {
|
||||
state.structure.rename(old, new);
|
||||
if &state.selected_structure_element == old {
|
||||
state.selected_structure_element = new.clone();
|
||||
}
|
||||
}
|
||||
state.popup = PopupWindowMode::None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,6 +146,13 @@ pub fn show_editable_stringtree(ui: &mut egui::Ui, state: &mut EditWindowUIState
|
|||
let mut string_selected = state.selected_structure_element.clone();
|
||||
ui.collapsing("Model Structure", |ui| {
|
||||
ui.vertical(|ui| {
|
||||
if state.selected_structure_element != "" {
|
||||
ui.label("Tree Element Selection: ".to_owned() + &state.selected_structure_element);
|
||||
if ui.button("deselect").clicked() {
|
||||
state.selected_structure_element = "".into();
|
||||
}
|
||||
ui.separator();
|
||||
}
|
||||
for each in &state.structure.root {
|
||||
match each {
|
||||
super::s_string_tree::StringTreeElement::None => {}
|
||||
|
@ -132,7 +165,8 @@ pub fn show_editable_stringtree(ui: &mut egui::Ui, state: &mut EditWindowUIState
|
|||
|
||||
if ui.add_enabled(true, but).clicked() {
|
||||
let mut should_close = false;
|
||||
if let PopupWindowMode::StructureElement(val) = &state.popup {
|
||||
if let PopupWindowMode::EditStructureElement(val, _) = &state.popup
|
||||
{
|
||||
if val == name {
|
||||
should_close = true;
|
||||
}
|
||||
|
@ -140,7 +174,10 @@ pub fn show_editable_stringtree(ui: &mut egui::Ui, state: &mut EditWindowUIState
|
|||
if should_close {
|
||||
state.popup = PopupWindowMode::None;
|
||||
} else {
|
||||
state.popup = PopupWindowMode::StructureElement(name.clone())
|
||||
state.popup = PopupWindowMode::EditStructureElement(
|
||||
name.clone(),
|
||||
name.clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -179,7 +216,7 @@ pub fn show_child(
|
|||
ui.radio_value(selection, name.clone(), name.clone());
|
||||
if ui.button("...").clicked() {
|
||||
let mut should_close = false;
|
||||
if let PopupWindowMode::StructureElement(val) = state {
|
||||
if let PopupWindowMode::EditStructureElement(val, _) = state {
|
||||
if val == name {
|
||||
should_close = true;
|
||||
}
|
||||
|
@ -187,7 +224,7 @@ pub fn show_child(
|
|||
if should_close {
|
||||
*state = PopupWindowMode::None;
|
||||
} else {
|
||||
*state = PopupWindowMode::StructureElement(name.clone())
|
||||
*state = PopupWindowMode::EditStructureElement(name.clone(), name.clone())
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,6 +8,7 @@ pub mod s_oct_asset;
|
|||
pub mod s_octtree;
|
||||
pub mod s_structure_asset;
|
||||
pub mod s_true_generic_octtree;
|
||||
pub mod s_identifier_validation;
|
||||
|
||||
pub const RANDOM_SPACE: f32 = 5.; // size of the random possibility space.
|
||||
pub const INTERVAL: f32 = 0.3; // how often to add ^ that many and remove ^ that many random locations
|
||||
|
|
|
@ -1,92 +1,145 @@
|
|||
use bevy::{
|
||||
math::{Quat, Vec3},
|
||||
transform::components::Transform,
|
||||
utils::hashbrown::HashMap,
|
||||
};
|
||||
|
||||
use crate::vvedit::s_string_tree::StringTree;
|
||||
use s_string_tree::StringTree;
|
||||
use bevy::{asset::{Asset, AssetLoader, AsyncReadExt}, reflect::TypePath, transform::components::Transform, utils::{hashbrown::HashMap, thiserror}};
|
||||
|
||||
pub struct ChildElPose {
|
||||
euler: Vec3,
|
||||
translation: Vec3,
|
||||
scale: Vec3,
|
||||
}
|
||||
pub enum StructureOptions {
|
||||
None,
|
||||
}
|
||||
impl ChildElPose {
|
||||
fn quat_from(&self) -> Quat {
|
||||
Quat::from_rotation_x(self.euler.x)
|
||||
+ Quat::from_rotation_y(self.euler.y)
|
||||
+ Quat::from_rotation_z(self.euler.z)
|
||||
}
|
||||
pub fn into_transform(&self) -> Transform {
|
||||
Transform::from_rotation(self.quat_from())
|
||||
* Transform::from_scale(self.scale)
|
||||
* Transform::from_translation(self.translation)
|
||||
}
|
||||
pub fn interpolate_toward(&self, other: &ChildElPose, t: f32) -> ChildElPose {
|
||||
let t = t.clamp(0., 1.);
|
||||
let rot = self.quat_from().slerp(other.quat_from(), t);
|
||||
let translation = self.translation.lerp(other.translation, t);
|
||||
let scale = self.scale.lerp(other.scale, t);
|
||||
Self::new_quat(rot, translation, scale)
|
||||
}
|
||||
pub fn interpolate(lhs: &ChildElPose, rhs: &ChildElPose, t: f32) -> ChildElPose {
|
||||
lhs.interpolate_toward(rhs, t)
|
||||
}
|
||||
pub fn combine_with(&self, other: &ChildElPose) -> ChildElPose {
|
||||
let rot = self.quat_from() + other.quat_from();
|
||||
let translation = self.translation + other.translation;
|
||||
let scale = self.scale * other.scale;
|
||||
Self::new_quat(rot, translation, scale)
|
||||
}
|
||||
pub fn combine(lhs: &ChildElPose, rhs: &ChildElPose) -> ChildElPose {
|
||||
lhs.combine_with(rhs)
|
||||
}
|
||||
pub fn new_euler(euler: Vec3, translation: Vec3, scale: Vec3) -> ChildElPose {
|
||||
ChildElPose {
|
||||
euler,
|
||||
translation,
|
||||
scale,
|
||||
}
|
||||
}
|
||||
pub fn new_quat(rot: Quat, translation: Vec3, scale: Vec3) -> ChildElPose {
|
||||
let int = rot.to_euler(bevy::math::EulerRot::XYZ);
|
||||
ChildElPose {
|
||||
euler: Vec3::new(int.0.to_degrees(), int.1.to_degrees(), int.2.to_degrees()),
|
||||
translation,
|
||||
scale,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use thiserror::Error;
|
||||
use crate::vvedit::s_string_tree;
|
||||
|
||||
#[derive(Asset, TypePath)]
|
||||
pub struct StructureAsset {
|
||||
shape: StringTree,
|
||||
base_pose: Pose,
|
||||
layout: StringTree,
|
||||
positions: HashMap<String, Transform>,
|
||||
}
|
||||
|
||||
pub struct Pose {
|
||||
elements: HashMap<String, ChildElPose>,
|
||||
#[derive(Default)]
|
||||
pub struct StructureLoader {
|
||||
//can anything even be put in here?
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_quaternion_euler_convs() {
|
||||
let start = Vec3::new(0., f32::to_radians(90.), f32::to_radians(45.));
|
||||
let quat = dbg!(Quat::from_euler(
|
||||
bevy::math::EulerRot::XYZ,
|
||||
start.x,
|
||||
start.y,
|
||||
start.z
|
||||
));
|
||||
let int = quat.normalize().to_euler(bevy::math::EulerRot::XYZ);
|
||||
let out = [int.0.to_degrees(), int.1.to_degrees(), int.2.to_degrees()];
|
||||
dbg!(&out);
|
||||
let quat2 = Quat::from_euler(
|
||||
bevy::math::EulerRot::XYZ,
|
||||
out[0].to_radians(),
|
||||
out[1].to_radians(),
|
||||
out[2].to_radians(),
|
||||
);
|
||||
assert!(quat2.normalize() == quat)
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StructureLoadError {
|
||||
#[error("Invalid File Data: {0}")]
|
||||
FileDataInvalid(String),
|
||||
#[error("FileNotFound: {0}")]
|
||||
FileNotFound(String),
|
||||
}
|
||||
|
||||
pub mod serialization {
|
||||
|
||||
pub mod meshes {
|
||||
use std::path::Path;
|
||||
|
||||
use bevy::{
|
||||
asset::io::{AssetSource, AssetWriter},
|
||||
tasks::block_on,
|
||||
};
|
||||
|
||||
use super::super::{StructureLoadError, StructureAsset};
|
||||
|
||||
pub fn load_detect_version(bytes: Vec<u8>) -> Result<StructureAsset, StructureLoadError> {
|
||||
return Err(StructureLoadError::FileDataInvalid("".to_string()));
|
||||
}
|
||||
|
||||
pub fn write_latest_version(path: &String, asset: &StructureAsset) -> bool {
|
||||
write_any_version(path, asset, Default::default())
|
||||
}
|
||||
|
||||
pub fn write_any_version(
|
||||
path: &String,
|
||||
asset: &StructureAsset,
|
||||
version: StructureVersions,
|
||||
) -> bool {
|
||||
if let Some(writer) = get_writer() {
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
if let Some(mut header) = version_header(version) {
|
||||
bytes.append(&mut header);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
match version {
|
||||
StructureVersions::Error => return false,
|
||||
StructureVersions::Version1 => {
|
||||
if let Some(mut contents) = versions::version_1::save(&asset) {
|
||||
bytes.append(&mut contents);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let res =
|
||||
block_on(async { writer.write_bytes(Path::new(path), bytes.as_slice()).await });
|
||||
return res.is_ok();
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn get_writer() -> Option<Box<dyn AssetWriter>> {
|
||||
AssetSource::get_default_writer("assets".into())(true)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub enum StructureVersions {
|
||||
#[default]
|
||||
Version1,
|
||||
Error,
|
||||
}
|
||||
|
||||
mod versions {
|
||||
|
||||
pub mod version_1 {
|
||||
|
||||
use super::super::super::super::{StructureLoadError, StructureAsset};
|
||||
pub fn load(data: std::str::Lines<'_>) -> Result<StructureAsset, StructureLoadError> {
|
||||
|
||||
Err(StructureLoadError::FileDataInvalid("".to_string()))
|
||||
}
|
||||
pub fn save(asset: &StructureAsset) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
const VERSION1: &str = "version 1";
|
||||
pub fn determine_version(line: Option<&str>) -> StructureVersions {
|
||||
if line.is_some() {
|
||||
let line: String = line.unwrap().into();
|
||||
if line.to_lowercase() == String::from(VERSION1) {
|
||||
return StructureVersions::Version1;
|
||||
}
|
||||
}
|
||||
StructureVersions::Error
|
||||
}
|
||||
pub fn version_header(version: StructureVersions) -> Option<Vec<u8>> {
|
||||
match version {
|
||||
StructureVersions::Error => None,
|
||||
StructureVersions::Version1 => Some((VERSION1.to_string()).as_bytes().to_vec()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AssetLoader for StructureLoader {
|
||||
type Asset = StructureAsset;
|
||||
type Settings = ();
|
||||
type Error = StructureLoadError;
|
||||
|
||||
fn load<'a>(
|
||||
&'a self,
|
||||
reader: &'a mut bevy::asset::io::Reader,
|
||||
_settings: &'a Self::Settings,
|
||||
_load_context: &'a mut bevy::asset::LoadContext,
|
||||
) -> bevy::utils::BoxedFuture<'a, Result<Self::Asset, Self::Error>> {
|
||||
Box::pin(async move {
|
||||
let mut bytes: Vec<u8> = Vec::<u8>::new();
|
||||
let result = reader.read_to_end(&mut bytes).await;
|
||||
if result.is_err() {
|
||||
return Err(StructureLoadError::FileNotFound(
|
||||
"could not read_to_end the bytes".to_string(),
|
||||
));
|
||||
}
|
||||
return serialization::meshes::load_detect_version(bytes);
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue