use crate::prelude::{GlobalTransform, Transform};
use bevy_ecs::{entity::Entity, hierarchy::ChildOf, system::EntityCommands, world::EntityWorldMut};
pub trait BuildChildrenTransformExt {
fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self;
fn remove_parent_in_place(&mut self) -> &mut Self;
}
impl BuildChildrenTransformExt for EntityCommands<'_> {
fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self {
self.queue(move |mut entity: EntityWorldMut| {
entity.set_parent_in_place(parent);
})
}
fn remove_parent_in_place(&mut self) -> &mut Self {
self.queue(move |mut entity: EntityWorldMut| {
entity.remove_parent_in_place();
})
}
}
impl BuildChildrenTransformExt for EntityWorldMut<'_> {
fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self {
let mut update_transform = || {
let child = self.id();
let parent_global = self.world_scope(|world| {
world
.get_entity_mut(parent)
.ok()?
.add_child(child)
.get::<GlobalTransform>()
.copied()
})?;
let child_global = self.get::<GlobalTransform>()?;
let new_child_local = child_global.reparented_to(&parent_global);
let mut child_local = self.get_mut::<Transform>()?;
*child_local = new_child_local;
Some(())
};
update_transform();
self
}
fn remove_parent_in_place(&mut self) -> &mut Self {
self.remove::<ChildOf>();
let mut update_transform = || {
let global = self.get::<GlobalTransform>()?;
let new_local = global.compute_transform();
let mut local = self.get_mut::<Transform>()?;
*local = new_local;
Some(())
};
update_transform();
self
}
}