Setup
This commit is contained in:
parent
20f333c931
commit
1bfac67b87
62
src/clone_entity_tree.rs
Normal file
62
src/clone_entity_tree.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
use bevy::{ecs::{query::QueryEntityError, system::Command}, prelude::*};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct EntityTreeNode {
|
||||||
|
pub source: Entity,
|
||||||
|
pub destination: Entity,
|
||||||
|
pub children: Vec<EntityTreeNode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityTreeNode {
|
||||||
|
pub fn from_entity_recursive(
|
||||||
|
commands: &mut Commands,
|
||||||
|
from_entity: Entity,
|
||||||
|
q_children: &Query<&Children>,
|
||||||
|
) -> EntityTreeNode {
|
||||||
|
let children = match q_children.get(from_entity) {
|
||||||
|
Ok(children) => children
|
||||||
|
.iter()
|
||||||
|
.map(|&child| {
|
||||||
|
EntityTreeNode::from_entity_recursive(
|
||||||
|
commands, child, q_children,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
Err(QueryEntityError::QueryDoesNotMatch(_)) => vec![],
|
||||||
|
Err(e) => panic!("{}", e),
|
||||||
|
};
|
||||||
|
EntityTreeNode {
|
||||||
|
source: from_entity,
|
||||||
|
destination: commands.spawn_empty().id(),
|
||||||
|
children,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = &EntityTreeNode> {
|
||||||
|
self.children.iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone_entity_tree(
|
||||||
|
world: &mut World,
|
||||||
|
EntityTreeNode {
|
||||||
|
source,
|
||||||
|
destination,
|
||||||
|
children,
|
||||||
|
}: &EntityTreeNode,
|
||||||
|
) {
|
||||||
|
//clone_entity_components(world, *source, *destination);
|
||||||
|
for node in children {
|
||||||
|
clone_entity_tree(world, node);
|
||||||
|
let mut destination = world.get_entity_mut(*destination).unwrap();
|
||||||
|
destination.add_child(node.destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// uses arc to prevent cloning the whole tree.
|
||||||
|
pub struct CloneEntityTree(Arc<EntityTreeNode>);
|
||||||
|
impl Command for CloneEntityTree {
|
||||||
|
fn apply(self, world: &mut World) {
|
||||||
|
clone_entity_tree(world, &self.0);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,8 @@
|
|||||||
mod markers;
|
mod markers;
|
||||||
mod plugin;
|
mod update;
|
||||||
mod queue;
|
mod setup;
|
||||||
|
mod state;
|
||||||
|
mod clone_entity_tree;
|
||||||
|
|
||||||
|
pub mod plugin;
|
||||||
|
pub mod needs_icon_marker;
|
21
src/markers.rs
Normal file
21
src/markers.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use bevy::ecs::component::Component;
|
||||||
|
|
||||||
|
/// The root of all the scenes that will be generated from this plugin.
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
pub struct IconCreatorRootMarker;
|
||||||
|
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
pub struct IconCreatorSceneRootMarker;
|
||||||
|
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
pub struct IconCreatorCameraMarker;
|
||||||
|
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
pub struct IconCreatorLightMarker;
|
||||||
|
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
pub struct IconCreatorEntityParentMarker;
|
||||||
|
|
||||||
|
/// Everything inside a scene should contain this marker with the scene's id.
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
pub struct InIconCreatorSceneMarker(pub u8);
|
@ -1,3 +0,0 @@
|
|||||||
|
|
||||||
/// The root of all the scenes that will be generated from this plugin.
|
|
||||||
pub struct IconCreatorRootMarker;
|
|
31
src/needs_icon_marker.rs
Normal file
31
src/needs_icon_marker.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use bevy::{ecs::component::Component, reflect::Reflect, transform::components::Transform, utils::Uuid};
|
||||||
|
|
||||||
|
/// Put this marker on any entity. This crate will then find this marker and copy all the entities underneath this entity,
|
||||||
|
/// then it will spawn them in the icon creator scene and once N number of frames have passed then render it to a texture.
|
||||||
|
#[derive(Debug, Component, Reflect, Default)]
|
||||||
|
pub struct NeedsIconMarker {
|
||||||
|
/// The transform to be applied to the parent entity when it gets spawned in the icon creator scene.
|
||||||
|
///
|
||||||
|
/// If this is None then the transform will just be a Transform::default()
|
||||||
|
pub(crate) transform: Option<Transform>,
|
||||||
|
/// The amount of frames that will be waited for the final image to be rendered once spawned.
|
||||||
|
///
|
||||||
|
/// This crate already waits 3 frames for the entity to be spawned.
|
||||||
|
pub(crate) extra_frames: Option<u8>,
|
||||||
|
/// With this identifier you will be able to look up the icon once it's created.
|
||||||
|
pub(crate) id: Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NeedsIconMarker {
|
||||||
|
pub fn new(id: Uuid) -> Self {
|
||||||
|
Self { transform: None, extra_frames: None, id }
|
||||||
|
}
|
||||||
|
pub fn with_transform(mut self, transform: Transform) -> Self {
|
||||||
|
self.transform = Some(transform);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn with_extra_frames(mut self, extra_frames: u8) -> Self {
|
||||||
|
self.extra_frames = Some(extra_frames);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,11 @@
|
|||||||
use bevy::{app::Plugin, math::Vec3};
|
use bevy::{app::{Plugin, Startup}, math::Vec3};
|
||||||
|
|
||||||
const DEFAULT_WORLD_POSITION_FOR_ROOT: Vec3 = Vec3 { x: 4000.0, y: -300.0, z: 4000.0 };
|
use crate::{setup::setup_icon_creation_scenes, state::IconCreatorState};
|
||||||
|
|
||||||
|
const DEFAULT_SCENES_AMOUNT: u8 = 1;
|
||||||
|
const DEFAULT_WORLD_POSITION_FOR_ROOT: Vec3 = Vec3 { x: 0.0, y: -300.0, z: 0.0 };
|
||||||
|
const DEFAULT_RENDER_LAYER: u8 = 21;
|
||||||
|
const DEFAULT_LIGHT_INTENSITY: f32 = 14_000.0;
|
||||||
|
|
||||||
/// Either use `IconCreatorPlugin::default()` or `IconCreatorPlugin::with_config(scenes)`
|
/// Either use `IconCreatorPlugin::default()` or `IconCreatorPlugin::with_config(scenes)`
|
||||||
pub struct IconCreatorPlugin {
|
pub struct IconCreatorPlugin {
|
||||||
@ -12,28 +17,37 @@ pub struct IconCreatorPlugin {
|
|||||||
scenes: u8,
|
scenes: u8,
|
||||||
/// The global coordinates of the Root of the scenes.
|
/// The global coordinates of the Root of the scenes.
|
||||||
///
|
///
|
||||||
/// Default is Vec3 { x: 4000.0, y: -300.0, z: 4000.0 }
|
/// Default is Vec3 { x: 0.0, y: -300.0, z: 0.0 }
|
||||||
world_pos: Vec3,
|
world_pos: Vec3,
|
||||||
}
|
/// The render layer everything inside this is going to be placed in
|
||||||
|
///
|
||||||
|
/// Default is 21
|
||||||
impl Default for IconCreatorPlugin {
|
render_layer: u8,
|
||||||
fn default() -> Self {
|
/// Default is 14,000
|
||||||
Self { scenes: 1, world_pos: DEFAULT_WORLD_POSITION_FOR_ROOT }
|
light_intensity: f32,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IconCreatorPlugin {
|
|
||||||
pub fn with_config(scenes: u8, world_pos: Vec3) -> Self {
|
|
||||||
Self {
|
|
||||||
scenes,
|
|
||||||
world_pos,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Plugin for IconCreatorPlugin {
|
impl Plugin for IconCreatorPlugin {
|
||||||
fn build(&self, app: &mut bevy::prelude::App) {
|
fn build(&self, app: &mut bevy::prelude::App) {
|
||||||
|
app.insert_resource(IconCreatorState::new(self.scenes, self.world_pos, self.render_layer, self.light_intensity));
|
||||||
|
|
||||||
|
app.add_systems(Startup, setup_icon_creation_scenes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for IconCreatorPlugin {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { scenes: DEFAULT_SCENES_AMOUNT, world_pos: DEFAULT_WORLD_POSITION_FOR_ROOT, render_layer: DEFAULT_RENDER_LAYER, light_intensity: DEFAULT_LIGHT_INTENSITY }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IconCreatorPlugin {
|
||||||
|
pub fn with_config(scenes: u8, world_pos: Vec3, render_layer: u8, light_intensity: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
scenes,
|
||||||
|
world_pos,
|
||||||
|
render_layer,
|
||||||
|
light_intensity,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +0,0 @@
|
|||||||
use bevy::ecs::system::Resource;
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Resource, Default, Debug, Clone)]
|
|
||||||
pub struct IconCreatorQueue {
|
|
||||||
|
|
||||||
}
|
|
81
src/setup.rs
Normal file
81
src/setup.rs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
use bevy::{prelude::*, render::{camera::ScalingMode, view::RenderLayers}};
|
||||||
|
|
||||||
|
use crate::{markers::{IconCreatorEntityParentMarker, IconCreatorRootMarker, IconCreatorSceneRootMarker, InIconCreatorSceneMarker}, state::IconCreatorState};
|
||||||
|
|
||||||
|
pub fn setup_icon_creation_scenes(
|
||||||
|
mut commands: Commands,
|
||||||
|
icon_creator_state: Res<IconCreatorState>,
|
||||||
|
) {
|
||||||
|
let icon_creator_root_entity = commands.spawn((
|
||||||
|
IconCreatorRootMarker,
|
||||||
|
TransformBundle::from_transform(Transform::from_translation(icon_creator_state.world_pos)),
|
||||||
|
VisibilityBundle::default(),
|
||||||
|
RenderLayers::layer(icon_creator_state.render_layer),
|
||||||
|
Name::new("Icon Creator Root Marker")
|
||||||
|
)).id();
|
||||||
|
for scene_id in 0..icon_creator_state.scenes {
|
||||||
|
// Scene Root
|
||||||
|
let scene_root_entity = commands
|
||||||
|
.spawn((
|
||||||
|
IconCreatorSceneRootMarker,
|
||||||
|
InIconCreatorSceneMarker(scene_id),
|
||||||
|
TransformBundle::default(),
|
||||||
|
VisibilityBundle::default(),
|
||||||
|
RenderLayers::layer(icon_creator_state.render_layer),
|
||||||
|
Name::new(format!("Scene Root with id: {scene_id}")),
|
||||||
|
))
|
||||||
|
.set_parent(icon_creator_root_entity)
|
||||||
|
.id();
|
||||||
|
// Camera
|
||||||
|
commands
|
||||||
|
.spawn((
|
||||||
|
InIconCreatorSceneMarker(scene_id),
|
||||||
|
Camera3dBundle {
|
||||||
|
camera: Camera {
|
||||||
|
order: -1,
|
||||||
|
clear_color: ClearColorConfig::Custom(Color::NONE),
|
||||||
|
is_active: false,
|
||||||
|
hdr: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
projection: Projection::Orthographic(OrthographicProjection {
|
||||||
|
scaling_mode: ScalingMode::Fixed { width: 1.0, height: 1.0 },
|
||||||
|
scale: 0.5,
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
transform: Transform::from_xyz(0.0, 0.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
RenderLayers::layer(icon_creator_state.render_layer),
|
||||||
|
Name::new("Scene camera"),
|
||||||
|
))
|
||||||
|
.set_parent(scene_root_entity);
|
||||||
|
// Light
|
||||||
|
commands
|
||||||
|
.spawn((
|
||||||
|
PointLightBundle {
|
||||||
|
point_light: PointLight {
|
||||||
|
intensity: icon_creator_state.light_intensity,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
transform: Transform::from_xyz(0.0, 0.0, 2.5),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
InIconCreatorSceneMarker(scene_id),
|
||||||
|
RenderLayers::layer(icon_creator_state.render_layer),
|
||||||
|
Name::new("Scene Point Light"),
|
||||||
|
))
|
||||||
|
.set_parent(scene_root_entity);
|
||||||
|
// Parent of the entities that will be spawned.
|
||||||
|
commands
|
||||||
|
.spawn((
|
||||||
|
IconCreatorEntityParentMarker,
|
||||||
|
InIconCreatorSceneMarker(scene_id),
|
||||||
|
TransformBundle::default(),
|
||||||
|
VisibilityBundle::default(),
|
||||||
|
RenderLayers::layer(icon_creator_state.render_layer),
|
||||||
|
Name::new("Scene Entity Parent"),
|
||||||
|
))
|
||||||
|
.set_parent(scene_root_entity);
|
||||||
|
}
|
||||||
|
}
|
15
src/state.rs
Normal file
15
src/state.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
use bevy::{ecs::system::Resource, math::Vec3};
|
||||||
|
|
||||||
|
#[derive(Resource, Debug)]
|
||||||
|
pub struct IconCreatorState {
|
||||||
|
pub(crate) scenes: u8,
|
||||||
|
pub(crate) world_pos: Vec3,
|
||||||
|
pub(crate) render_layer: u8,
|
||||||
|
pub(crate) light_intensity: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IconCreatorState {
|
||||||
|
pub fn new(scenes: u8, world_pos: Vec3, render_layer: u8, light_intensity: f32) -> Self {
|
||||||
|
Self { scenes, world_pos, render_layer, light_intensity }
|
||||||
|
}
|
||||||
|
}
|
0
src/update.rs
Normal file
0
src/update.rs
Normal file
Loading…
Reference in New Issue
Block a user