diff --git a/src/vvlib/mod.rs b/src/vvlib/mod.rs index 5fbb69b..59f4346 100644 --- a/src/vvlib/mod.rs +++ b/src/vvlib/mod.rs @@ -3,8 +3,13 @@ use bevy::app::App; use bevy::app::Last; use bevy::app::Plugin; +use bevy::asset::AssetServer; +use bevy::asset::Assets; +use bevy::asset::Handle; use bevy::ecs::component::Component; use bevy::ecs::system::Query; +use bevy::ecs::system::Res; +use bevy::ecs::system::ResMut; use bevy::math::Vec3; use bevy::render::color::Color; use bevy::render::mesh::Indices; @@ -124,15 +129,61 @@ impl Plugin for OctTreePlugin { #[derive(Component)] pub struct OctTreeModelComponent { model: octtree::OctTree, + handle: Option>, //TODO: add Option<> handle for remeshing-event for async-computing it - so if it gets edited again we can cancel the old one and let it run a new mesher async compute } /// schedules re-meshing updates of the models used to represent oct-tree data. collisions are instantly updated (as any update to the oct-tree itself updates the data used for collisioning, so we can be lazy about when the visuals kick in (to an extent, of course). as such, we want to kick them into an async updater for the meshes used) -pub fn oct_tree_edit_updater(mut query: Query<&mut OctTreeModelComponent>) { +pub fn oct_tree_edit_updater( + mut query: Query<&mut OctTreeModelComponent>, + mut mesh_assets: ResMut>, +) { for mut model in &mut query { - if model.model.needs_update { - // spawn remeshing async task, put in the model + if model.handle.is_none() && model.model.needs_update { + let meshed = model.render_as_mesh(); + let handle = mesh_assets.add(meshed); + model.handle = Some(handle); + // TODO: refactor to spawn remeshing async task, put in the model model.model.needs_update = false; + } else if model.model.needs_update && model.handle.is_some() { + // + let meshed = model.render_as_mesh(); + let mut in_place = mesh_assets.get_mut(model.handle.clone().unwrap()); + if in_place.is_some() { + let mut in_place = in_place.unwrap(); + + in_place.remove_attribute(Mesh::ATTRIBUTE_POSITION); + let att_pos = meshed.attribute(Mesh::ATTRIBUTE_POSITION); + if att_pos.is_some() { + in_place.insert_attribute(Mesh::ATTRIBUTE_POSITION, att_pos.unwrap().clone()); + } else { + panic!("no position attribute on newly generated mesh?"); + } + + in_place.remove_attribute(Mesh::ATTRIBUTE_COLOR); + let att_col = meshed.attribute(Mesh::ATTRIBUTE_COLOR); + if att_col.is_some() { + in_place.insert_attribute(Mesh::ATTRIBUTE_COLOR, att_col.unwrap().clone()); + } else { + panic!("no color attribute on newly generated mesh?"); + } + + in_place.remove_attribute(Mesh::ATTRIBUTE_NORMAL); + let att_norm = meshed.attribute(Mesh::ATTRIBUTE_NORMAL); + if att_norm.is_some() { + in_place.insert_attribute(Mesh::ATTRIBUTE_POSITION, att_norm.unwrap().clone()); + } else { + panic!("no normal attribute on newly generated mesh?"); + } + + in_place.remove_indices(); + let att_ind = meshed.indices(); + if att_ind.is_some() { + in_place.insert_indices(att_ind.unwrap().clone()); + } else { + panic!("no indices on newly generated mesh?"); + } + } } } }