Skip to content

Commit

Permalink
functional scenario switching
Browse files Browse the repository at this point in the history
Signed-off-by: Reuben Thomas <reubenthomas123@gmail.com>
  • Loading branch information
reuben-thomas committed Jul 17, 2024
1 parent 7adb5c6 commit ce9f345
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 52 deletions.
22 changes: 2 additions & 20 deletions rmf_site_editor/src/site/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@

use crate::{recency::RecencyRanking, site::*, WorkspaceMarker};
use bevy::{ecs::system::SystemParam, prelude::*};
use std::{
collections::{BTreeMap, HashMap},
path::PathBuf,
};
use std::{collections::HashMap, path::PathBuf};
use thiserror::Error as ThisError;

/// This component is given to the site to keep track of what file it should be
Expand Down Expand Up @@ -256,27 +253,12 @@ fn generate_site_entities(
consider_id(*model_description_id);
}

let (default_scenario_id, default_scenario) = site_data
.scenarios
.first_key_value()
.expect("No scenarios found");
let active_model_instance_ids: std::collections::HashSet<u32> = default_scenario
.scenario
.added_model_instances
.iter()
.map(|(id, _)| *id)
.collect();
for (model_instance_id, model_instance) in &site_data.model_instances {
let model_instance = model_instance.convert(&id_to_entity).for_site(site_id)?;
let model_instance_parent = if active_model_instance_ids.contains(model_instance_id) {
model_instance.parent.0.unwrap_or(site_id)
} else {
site_id
};
let model_instance_entity = commands
.spawn(model_instance.clone())
.insert(SiteID(*model_instance_id))
.set_parent(model_instance_parent)
.set_parent(site_id)
.id();
id_to_entity.insert(*model_instance_id, model_instance_entity);
consider_id(*model_instance_id);
Expand Down
12 changes: 4 additions & 8 deletions rmf_site_editor/src/site/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

use crate::{
interaction::{DragPlaneBundle, Selectable, MODEL_PREVIEW_LAYER},
site::{Category, Group, Members, PreventDeletion, SiteAssets},
site::{Category, Group, PreventDeletion, SiteAssets},
site_asset_io::MODEL_ENVIRONMENT_VARIABLE,
};
use bevy::{
Expand All @@ -31,8 +31,7 @@ use rmf_site_format::{
Affiliation, AssetSource, ModelMarker, ModelProperty, NameInSite, Pending, Pose, Scale,
};
use smallvec::SmallVec;
use std::{any::TypeId, collections::HashMap};
use yaserde::xml::name;
use std::any::TypeId;

#[derive(Component, Debug, Clone)]
pub struct ModelScene {
Expand Down Expand Up @@ -490,15 +489,15 @@ pub fn propagate_model_render_layers(

pub fn update_model_instances<T: Component + Default + Clone>(
mut commands: Commands,
mut model_properties: Query<
model_properties: Query<
(Entity, &NameInSite, Ref<ModelProperty<T>>),
(With<ModelMarker>, With<Group>),
>,
model_instances: Query<(Entity, Ref<Affiliation<Entity>>), (With<ModelMarker>, Without<Group>)>,
) {
for (instance_entity, affiliation) in model_instances.iter() {
if let Some(description_entity) = affiliation.0 {
if let Ok((_, name, property)) = model_properties.get(description_entity) {
if let Ok((_, _, property)) = model_properties.get(description_entity) {
if property.is_changed() || affiliation.is_changed() {
let mut cmd = commands.entity(instance_entity);
cmd.remove::<ModelProperty<T>>();
Expand All @@ -508,6 +507,3 @@ pub fn update_model_instances<T: Component + Default + Clone>(
}
}
}

#[derive(Component)]
pub struct Inactive;
105 changes: 93 additions & 12 deletions rmf_site_editor/src/site/scenario.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,116 @@
*
*/

use crate::site::CurrentScenario;
use crate::{site::CurrentScenario, CurrentWorkspace};
use bevy::prelude::*;
use rmf_site_format::{Group, ModelMarker, NameInSite, Pose};
use rmf_site_format::{Group, ModelMarker, NameInSite, Pose, Scenario, SiteParent};
use std::collections::HashMap;

#[derive(Clone, Copy, Debug, Event)]
pub struct ChangeCurrentScenario(pub Entity);

pub fn update_current_scenario(
mut commands: Commands,
mut change_current_scenario: EventReader<ChangeCurrentScenario>,
mut current_scenario: ResMut<CurrentScenario>,
scenarios: Query<Entity, &NameInSite>,
current_workspace: Res<CurrentWorkspace>,
scenarios: Query<&Scenario<Entity>>,
mut model_instances: Query<
(Entity, &mut Pose, &SiteParent<Entity>, &mut Visibility),
(With<ModelMarker>, Without<Group>),
>,
) {
for ChangeCurrentScenario(new_scenario_entity) in change_current_scenario.read() {
*current_scenario = CurrentScenario(Some(*new_scenario_entity));
println!("Changed scenario");
for ChangeCurrentScenario(scenario_entity) in change_current_scenario.read() {
// Used to build a scenario from root
let mut scenario_stack = Vec::<&Scenario<Entity>>::new();
let mut scenario = scenarios
.get(*scenario_entity)
.expect("Failed to get scenario entity");
loop {
scenario_stack.push(scenario);
if let Some(scenario_parent) = scenario.parent_scenario.0 {
scenario = scenarios
.get(scenario_parent)
.expect("Scenario parent doesn't exist");
} else {
break;
}
}

// Iterate stack to identify instances and poses in this model
let mut active_model_instances = HashMap::<Entity, Pose>::new();
for scenario in scenario_stack.iter().rev() {
for (e, pose) in scenario.added_model_instances.iter() {
active_model_instances.insert(*e, pose.clone());
}
for (e, pose) in scenario.moved_model_instances.iter() {
active_model_instances.insert(*e, pose.clone());
}
for e in scenario.removed_model_instances.iter() {
active_model_instances.remove(e);
}
}

let current_site_entity = match current_workspace.root {
Some(current_site) => current_site,
None => return,
};

// If active, assign parent to level, otherwise assign parent to site
for (entity, mut pose, parent, mut visibility) in model_instances.iter_mut() {
if let Some(new_pose) = active_model_instances.get(&entity) {
commands.entity(entity).set_parent(parent.0.unwrap());
*pose = new_pose.clone();
*visibility = Visibility::Inherited;
} else {
commands.entity(entity).set_parent(current_site_entity);
*visibility = Visibility::Hidden;
}
}

*current_scenario = CurrentScenario(Some(*scenario_entity));
}
}

pub fn update_scenario_properties(
current_scenario: Res<CurrentScenario>,
mut scenarios: Query<&mut Scenario<Entity>>,
changed_models: Query<(Entity, &NameInSite, Ref<Pose>), (With<ModelMarker>, Without<Group>)>,
) {
for (e, name, pose) in changed_models.iter() {
if pose.is_added() {
println!("Added: {}", name.0);
}
if let Some(mut current_scenario) = current_scenario
.0
.and_then(|entity| scenarios.get_mut(entity).ok())
{
for (entity, _, pose) in changed_models.iter() {
if pose.is_changed() {
let existing_added_model = current_scenario
.added_model_instances
.iter_mut()
.find(|(e, _)| *e == entity);
if let Some(existing_added_model) = existing_added_model {
existing_added_model.1 = pose.clone();
return;
} else if pose.is_added() {
current_scenario
.added_model_instances
.push((entity, pose.clone()));
return;
}

if !pose.is_added() && pose.is_changed() {
println!("Moved: {}", name.0)
let existing_moved_model = current_scenario
.moved_model_instances
.iter_mut()
.find(|(e, _)| *e == entity);
if let Some(existing_moved_model) = existing_moved_model {
existing_moved_model.1 = pose.clone();
return;
} else {
current_scenario
.moved_model_instances
.push((entity, pose.clone()));
return;
}
}
}
}
}
34 changes: 32 additions & 2 deletions rmf_site_editor/src/site/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@

use crate::{interaction::CameraControls, CurrentWorkspace};
use bevy::prelude::*;
use itertools::Itertools;
use rmf_site_format::{
LevelElevation, LevelProperties, NameInSite, NameOfSite, Pose, UserCameraPoseMarker,
LevelElevation, LevelProperties, NameInSite, NameOfSite, Pose, ScenarioBundle, ScenarioMarker,
UserCameraPoseMarker,
};

use super::ChangeCurrentScenario;

/// Used as an event to command that a new site should be made the current one
#[derive(Clone, Copy, Debug, Event)]
pub struct ChangeCurrentSite {
Expand Down Expand Up @@ -50,15 +54,17 @@ pub struct NextSiteID(pub u32);
pub fn change_site(
mut commands: Commands,
mut change_current_site: EventReader<ChangeCurrentSite>,
mut change_current_scenario: EventWriter<ChangeCurrentScenario>,
mut current_workspace: ResMut<CurrentWorkspace>,
mut current_level: ResMut<CurrentLevel>,
mut current_scenario: ResMut<CurrentScenario>,
current_scenario: ResMut<CurrentScenario>,
cached_levels: Query<&CachedLevel>,
mut visibility: Query<&mut Visibility>,
open_sites: Query<Entity, With<NameOfSite>>,
children: Query<&Children>,
parents: Query<&Parent>,
levels: Query<Entity, With<LevelElevation>>,
scenarios: Query<Entity, With<ScenarioMarker>>,
) {
let mut set_visibility = |entity, value| {
if let Ok(mut v) = visibility.get_mut(entity) {
Expand Down Expand Up @@ -139,6 +145,30 @@ pub fn change_site(
}
}
}

if let Some(new_scenario) = cmd.scenario {
if let Some(previous_scenario) = current_scenario.0 {
if previous_scenario != new_scenario {
change_current_scenario.send(ChangeCurrentScenario(new_scenario));
}
}
} else {
if let Ok(children) = children.get(cmd.site) {
let any_scenario = children
.iter()
.filter(|child| scenarios.get(**child).is_ok())
.find_or_first(|_| true);
if let Some(new_scenario) = any_scenario {
change_current_scenario.send(ChangeCurrentScenario(*new_scenario));
} else {
let new_scenario = commands
.spawn(ScenarioBundle::<Entity>::default())
.set_parent(cmd.site)
.id();
change_current_scenario.send(ChangeCurrentScenario(new_scenario));
}
}
}
}
}

Expand Down
8 changes: 3 additions & 5 deletions rmf_site_editor/src/widgets/inspector/inspect_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

use crate::{
site::{
Affiliation, AssetSource, Change, DefaultFile, Group, IsStatic, Members, ModelProperty,
NameInSite, Scale, Texture,
Affiliation, AssetSource, Change, DefaultFile, Group, Members, ModelProperty, NameInSite,
Texture,
},
widgets::{inspector::InspectTexture, prelude::*, Inspect, SelectorWidget},
CurrentWorkspace,
Expand All @@ -33,8 +33,6 @@ pub struct InspectGroup<'w, 's> {
names: Query<'w, 's, &'static NameInSite>,
textures: Query<'w, 's, &'static Texture>,
model_assets: Query<'w, 's, &'static ModelProperty<AssetSource>>,
is_static: Query<'w, 's, &'static ModelProperty<AssetSource>>,
scale: Query<'w, 's, &'static ModelProperty<Scale>>,
members: Query<'w, 's, &'static Members>,
default_file: Query<'w, 's, &'static DefaultFile>,
current_workspace: Res<'w, CurrentWorkspace>,
Expand Down Expand Up @@ -73,7 +71,7 @@ impl<'w, 's> InspectGroup<'w, 's> {
.root
.map(|e| self.default_file.get(e).ok())
.flatten();
if let Ok(ModelProperty(asset)) = self.model_assets.get(id) {
if let Ok(ModelProperty(_)) = self.model_assets.get(id) {
ui.label(RichText::new("Model Description Properties").size(18.0));
ui.add_space(10.0);
}
Expand Down
2 changes: 1 addition & 1 deletion rmf_site_editor/src/widgets/view_groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl<'w, 's> ViewGroups<'w, 's> {
});

for child in children {
let Ok((name, asset_source, site_id)) = q_groups.get(*child) else {
let Ok((name, _, site_id)) = q_groups.get(*child) else {
continue;
};
let text = site_id
Expand Down
7 changes: 3 additions & 4 deletions rmf_site_editor/src/widgets/view_scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
ScenarioMarker,
},
widgets::prelude::*,
AppState, Icons,
Icons,
};
use bevy::{ecs::system::SystemParam, prelude::*};
use bevy_egui::egui::{Button, CollapsingHeader, Color32, Ui};
Expand Down Expand Up @@ -212,7 +212,7 @@ impl<'w, 's> ViewScenarios<'w, 's> {
let mut version = 1;
self.scenarios
.iter()
.filter(|(e, name, scenario)| scenario.parent_scenario.0.is_none())
.filter(|(_, _, scenario)| scenario.parent_scenario.0.is_none())
.for_each(|(scenario_entity, _, _)| {
show_scenario_widget(
ui,
Expand Down Expand Up @@ -244,7 +244,7 @@ fn show_scenario_widget(
>,
icons: &Res<Icons>,
) {
let (entity, name, scenario) = q_scenario.get(scenario_entity).unwrap();
let (entity, name, _) = q_scenario.get(scenario_entity).unwrap();
let scenario_version_str = scenario_version
.iter()
.map(|v| v.to_string())
Expand All @@ -257,7 +257,6 @@ fn show_scenario_widget(
change_current_scenario.send(ChangeCurrentScenario(entity));
}
ui.colored_label(Color32::DARK_GRAY, scenario_version_str.clone());
ui.label(name.0.clone());
let mut new_name = name.0.clone();
if ui.text_edit_singleline(&mut new_name).changed() {
change_name.send(Change::new(NameInSite(new_name), entity));
Expand Down

0 comments on commit ce9f345

Please sign in to comment.