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 plugin;
|
||||
mod queue;
|
||||
mod update;
|
||||
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)`
|
||||
pub struct IconCreatorPlugin {
|
||||
@ -12,28 +17,37 @@ pub struct IconCreatorPlugin {
|
||||
scenes: u8,
|
||||
/// 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,
|
||||
}
|
||||
|
||||
|
||||
impl Default for IconCreatorPlugin {
|
||||
fn default() -> Self {
|
||||
Self { scenes: 1, world_pos: DEFAULT_WORLD_POSITION_FOR_ROOT }
|
||||
}
|
||||
}
|
||||
|
||||
impl IconCreatorPlugin {
|
||||
pub fn with_config(scenes: u8, world_pos: Vec3) -> Self {
|
||||
Self {
|
||||
scenes,
|
||||
world_pos,
|
||||
}
|
||||
}
|
||||
/// The render layer everything inside this is going to be placed in
|
||||
///
|
||||
/// Default is 21
|
||||
render_layer: u8,
|
||||
/// Default is 14,000
|
||||
light_intensity: f32,
|
||||
}
|
||||
|
||||
impl Plugin for IconCreatorPlugin {
|
||||
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