ui: rework so Nodes now use transforms and z-sort happens
This commit is contained in:
parent
75429f4639
commit
1ef4fbf005
@ -77,14 +77,12 @@ pub fn run_on_hierarchy_subworld<T>(
|
||||
pub fn run_on_hierarchy_subworld_mut<T>(
|
||||
world: &mut SubWorld,
|
||||
entity: Entity,
|
||||
input: T,
|
||||
run: &mut dyn FnMut(&mut SubWorld, Entity, T) -> Option<T>,
|
||||
child_result_action: &mut dyn FnMut(T, T) -> T,
|
||||
) -> Option<T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
parent_result: Option<&mut T>,
|
||||
mut previous_result: Option<T>,
|
||||
run: &mut dyn FnMut(&mut SubWorld, Entity, Option<&mut T>, Option<T>) -> Option<T>,
|
||||
) -> Option<T> where T: Clone {
|
||||
// TODO: not a huge fan of this pattern. are there ways to do recursive updates in legion without allocations?
|
||||
// TODO: the problem above might be resolvable with world splitting
|
||||
let children = match world.get_component::<Children>(entity) {
|
||||
Some(children) => Some(
|
||||
children
|
||||
@ -95,21 +93,21 @@ where
|
||||
None => None,
|
||||
};
|
||||
|
||||
let result = run(world, entity, input);
|
||||
|
||||
if let Some(mut result) = result {
|
||||
if let Some(children) = children {
|
||||
for child in children {
|
||||
let child_result =
|
||||
run_on_hierarchy_subworld_mut(world, child, result, run, child_result_action);
|
||||
if let Some(child_result) = child_result {
|
||||
result = child_result_action(result, child_result)
|
||||
}
|
||||
}
|
||||
let mut parent_result = run(world, entity, parent_result, previous_result);
|
||||
previous_result = None;
|
||||
if let Some(children) = children {
|
||||
for child in children {
|
||||
previous_result = run_on_hierarchy_subworld_mut(
|
||||
world,
|
||||
child,
|
||||
parent_result.as_mut(),
|
||||
previous_result,
|
||||
run,
|
||||
);
|
||||
}
|
||||
|
||||
Some(result)
|
||||
} else {
|
||||
None
|
||||
previous_result = parent_result;
|
||||
}
|
||||
|
||||
previous_result
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ impl OrthographicCameraEntity {
|
||||
..Default::default()
|
||||
},
|
||||
orthographic_projection: OrthographicProjection {
|
||||
window_origin: WindowOrigin::BottomLeft,
|
||||
window_origin: WindowOrigin::Center,
|
||||
..Default::default()
|
||||
},
|
||||
visible_entities: Default::default(),
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
mod color_material;
|
||||
mod dynamic_texture_atlas_builder;
|
||||
pub mod entity;
|
||||
mod quad;
|
||||
mod rect;
|
||||
mod render;
|
||||
mod sprite;
|
||||
@ -10,7 +9,6 @@ mod texture_atlas_builder;
|
||||
|
||||
pub use color_material::*;
|
||||
pub use dynamic_texture_atlas_builder::*;
|
||||
pub use quad::*;
|
||||
pub use rect::*;
|
||||
pub use render::*;
|
||||
pub use sprite::*;
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
use bevy_core::bytes::Bytes;
|
||||
use bevy_render::render_resource::{RenderResource, RenderResources};
|
||||
use glam::Vec2;
|
||||
#[repr(C)]
|
||||
#[derive(Default, Clone, Copy, Debug, RenderResources, RenderResource, Bytes)]
|
||||
#[render_resources(from_self)]
|
||||
pub struct Quad {
|
||||
pub position: Vec2,
|
||||
pub size: Vec2,
|
||||
pub z_index: f32,
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::{ColorMaterial, Quad, TextureAtlas, TextureAtlasSprite, Sprite};
|
||||
use crate::{ColorMaterial, TextureAtlas, TextureAtlasSprite, Sprite};
|
||||
use bevy_asset::{Assets, Handle};
|
||||
use bevy_render::{
|
||||
base_render_graph,
|
||||
@ -110,7 +110,6 @@ pub fn build_sprite_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor
|
||||
|
||||
pub mod node {
|
||||
pub const COLOR_MATERIAL: &'static str = "color_material";
|
||||
pub const QUAD: &'static str = "quad";
|
||||
pub const SPRITE: &'static str = "sprite";
|
||||
pub const SPRITE_SHEET: &'static str = "sprite_sheet";
|
||||
pub const SPRITE_SHEET_SPRITE: &'static str = "sprite_sheet_sprite";
|
||||
@ -129,9 +128,6 @@ impl SpriteRenderGraphBuilder for RenderGraph {
|
||||
self.add_node_edge(node::COLOR_MATERIAL, base_render_graph::node::MAIN_PASS)
|
||||
.unwrap();
|
||||
|
||||
self.add_system_node(node::QUAD, RenderResourcesNode::<Quad>::new(false));
|
||||
self.add_node_edge(node::QUAD, base_render_graph::node::MAIN_PASS)
|
||||
.unwrap();
|
||||
self.add_system_node(node::SPRITE, RenderResourcesNode::<Sprite>::new(true));
|
||||
self.add_node_edge(node::SPRITE, base_render_graph::node::MAIN_PASS)
|
||||
.unwrap();
|
||||
|
||||
@ -2,28 +2,52 @@ use super::Node;
|
||||
use crate::{render::UI_PIPELINE_HANDLE, widget::Label};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_derive::EntityArchetype;
|
||||
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::RenderPipelines};
|
||||
use bevy_sprite::{ColorMaterial, Quad, QUAD_HANDLE};
|
||||
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::{PipelineSpecialization, RenderPipelines, DynamicBinding, RenderPipeline}};
|
||||
use bevy_sprite::{ColorMaterial, QUAD_HANDLE};
|
||||
use bevy_transform::prelude::{Translation, Transform, Rotation, Scale};
|
||||
|
||||
#[derive(EntityArchetype)]
|
||||
pub struct UiEntity {
|
||||
pub node: Node,
|
||||
pub quad: Quad,
|
||||
pub mesh: Handle<Mesh>, // TODO: maybe abstract this out
|
||||
pub material: Handle<ColorMaterial>,
|
||||
pub draw: Draw,
|
||||
pub render_pipelines: RenderPipelines,
|
||||
pub transform: Transform,
|
||||
pub translation: Translation,
|
||||
pub rotation: Rotation,
|
||||
pub scale: Scale,
|
||||
}
|
||||
|
||||
impl Default for UiEntity {
|
||||
fn default() -> Self {
|
||||
UiEntity {
|
||||
mesh: QUAD_HANDLE,
|
||||
render_pipelines: RenderPipelines::from_handles(&[UI_PIPELINE_HANDLE]),
|
||||
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::specialized(
|
||||
UI_PIPELINE_HANDLE,
|
||||
PipelineSpecialization {
|
||||
dynamic_bindings: vec![
|
||||
// Transform
|
||||
DynamicBinding {
|
||||
bind_group: 1,
|
||||
binding: 0,
|
||||
},
|
||||
// Node_size
|
||||
DynamicBinding {
|
||||
bind_group: 1,
|
||||
binding: 1,
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
)]),
|
||||
node: Default::default(),
|
||||
quad: Default::default(),
|
||||
material: Default::default(),
|
||||
draw: Default::default(),
|
||||
transform: Default::default(),
|
||||
translation: Default::default(),
|
||||
rotation: Default::default(),
|
||||
scale: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -31,9 +55,12 @@ impl Default for UiEntity {
|
||||
#[derive(EntityArchetype)]
|
||||
pub struct LabelEntity {
|
||||
pub node: Node,
|
||||
pub quad: Quad,
|
||||
pub draw: Draw,
|
||||
pub label: Label,
|
||||
pub transform: Transform,
|
||||
pub translation: Translation,
|
||||
pub rotation: Rotation,
|
||||
pub scale: Scale,
|
||||
}
|
||||
|
||||
impl Default for LabelEntity {
|
||||
@ -41,8 +68,14 @@ impl Default for LabelEntity {
|
||||
LabelEntity {
|
||||
label: Label::default(),
|
||||
node: Default::default(),
|
||||
quad: Default::default(),
|
||||
draw: Default::default(),
|
||||
draw: Draw {
|
||||
is_transparent: true,
|
||||
..Default::default()
|
||||
},
|
||||
transform: Default::default(),
|
||||
translation: Default::default(),
|
||||
rotation: Default::default(),
|
||||
scale: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ pub struct UiPlugin;
|
||||
|
||||
impl AppPlugin for UiPlugin {
|
||||
fn build(&self, app: &mut AppBuilder) {
|
||||
app.add_system_to_stage(stage::POST_UPDATE, ui_update_system())
|
||||
app.add_system_to_stage(stage::POST_UPDATE, ui_update_system.system())
|
||||
.add_system_to_stage(stage::POST_UPDATE, Label::label_system.system())
|
||||
.add_system_to_stage(bevy_render::stage::DRAW, Label::draw_label_system.system());
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use super::{Anchors, Margins};
|
||||
use bevy_sprite::Quad;
|
||||
use glam::Vec2;
|
||||
use bevy_transform::prelude::Translation;
|
||||
use bevy_render::render_resource::RenderResources;
|
||||
use glam::{Vec2, Vec3};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum MarginGrowDirection {
|
||||
@ -8,41 +9,37 @@ enum MarginGrowDirection {
|
||||
Positive,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Default, RenderResources)]
|
||||
pub struct Node {
|
||||
pub size: Vec2,
|
||||
#[render_resources(ignore)]
|
||||
pub position: Vec2,
|
||||
#[render_resources(ignore)]
|
||||
pub anchors: Anchors,
|
||||
#[render_resources(ignore)]
|
||||
pub margins: Margins,
|
||||
}
|
||||
|
||||
impl Default for Node {
|
||||
fn default() -> Self {
|
||||
impl Node {
|
||||
pub fn new(anchors: Anchors, margins: Margins) -> Self {
|
||||
Node {
|
||||
position: Vec2::default(),
|
||||
anchors: Anchors::default(),
|
||||
margins: Margins::default(),
|
||||
anchors,
|
||||
margins,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn new(position: Vec2, anchors: Anchors, margins: Margins) -> Self {
|
||||
pub fn positioned(position: Vec2, anchors: Anchors, margins: Margins) -> Self {
|
||||
Node {
|
||||
position,
|
||||
anchors,
|
||||
margins,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
quad: &mut Quad,
|
||||
parent_size: Vec2,
|
||||
parent_position: Vec2,
|
||||
z_index: f32,
|
||||
) {
|
||||
pub fn update(&mut self, translation: &mut Translation, z_offset: f32, parent_size: Vec2) {
|
||||
let (quad_x, quad_width) = Self::compute_dimension_properties(
|
||||
self.position.x(),
|
||||
self.margins.left,
|
||||
self.margins.right,
|
||||
self.anchors.left,
|
||||
@ -50,7 +47,6 @@ impl Node {
|
||||
parent_size.x(),
|
||||
);
|
||||
let (quad_y, quad_height) = Self::compute_dimension_properties(
|
||||
self.position.y(),
|
||||
self.margins.bottom,
|
||||
self.margins.top,
|
||||
self.anchors.bottom,
|
||||
@ -58,13 +54,11 @@ impl Node {
|
||||
parent_size.y(),
|
||||
);
|
||||
|
||||
quad.size = Vec2::new(quad_width, quad_height);
|
||||
quad.position = Vec2::new(quad_x, quad_y) + parent_position;
|
||||
quad.z_index = z_index;
|
||||
self.size = Vec2::new(quad_width, quad_height);
|
||||
translation.0 = self.position.extend(0.0) + Vec3::new(quad_x, quad_y, z_offset) - (parent_size / 2.0).extend(0.0);
|
||||
}
|
||||
|
||||
fn compute_dimension_properties(
|
||||
offset: f32,
|
||||
margin0: f32,
|
||||
margin1: f32,
|
||||
anchor0: f32,
|
||||
@ -85,23 +79,22 @@ impl Node {
|
||||
MarginGrowDirection::Negative
|
||||
};
|
||||
|
||||
let p0 = Self::compute_quad_position(offset, margin0, anchor_p0, p0_grow_direction);
|
||||
let p1 = Self::compute_quad_position(offset, margin1, anchor_p1, p1_grow_direction);
|
||||
let p0 = Self::compute_anchored_position(margin0, anchor_p0, p0_grow_direction);
|
||||
let p1 = Self::compute_anchored_position(margin1, anchor_p1, p1_grow_direction);
|
||||
|
||||
let final_width = p1 - p0;
|
||||
let p = (p0 + p1) / 2.0;
|
||||
(p, final_width.abs())
|
||||
}
|
||||
|
||||
fn compute_quad_position(
|
||||
position: f32,
|
||||
fn compute_anchored_position(
|
||||
margin: f32,
|
||||
anchor_position: f32,
|
||||
grow_direction: MarginGrowDirection,
|
||||
) -> f32 {
|
||||
match grow_direction {
|
||||
MarginGrowDirection::Negative => position + anchor_position - margin,
|
||||
MarginGrowDirection::Positive => position + anchor_position + margin,
|
||||
MarginGrowDirection::Negative => anchor_position - margin,
|
||||
MarginGrowDirection::Positive => anchor_position + margin,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,11 +2,12 @@ use bevy_asset::{Assets, Handle};
|
||||
use bevy_render::{
|
||||
base_render_graph,
|
||||
pipeline::{state_descriptors::*, PipelineDescriptor},
|
||||
render_graph::{nodes::{PassNode, CameraNode}, RenderGraph},
|
||||
render_graph::{nodes::{PassNode, CameraNode, RenderResourcesNode}, RenderGraph},
|
||||
shader::{Shader, ShaderStage, ShaderStages},
|
||||
texture::TextureFormat, ActiveCameras,
|
||||
};
|
||||
use legion::prelude::Resources;
|
||||
use crate::Node;
|
||||
|
||||
pub const UI_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
|
||||
Handle::from_u128(323432002226399387835192542539754486265);
|
||||
@ -58,6 +59,7 @@ pub fn build_ui_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||
|
||||
pub mod node {
|
||||
pub const UI_CAMERA: &'static str = "ui_camera";
|
||||
pub const NODE: &'static str = "node";
|
||||
}
|
||||
|
||||
pub mod camera {
|
||||
@ -78,6 +80,9 @@ impl UiRenderGraphBuilder for RenderGraph {
|
||||
self.add_system_node(node::UI_CAMERA, CameraNode::new(camera::UI_CAMERA));
|
||||
self.add_node_edge(node::UI_CAMERA, base_render_graph::node::MAIN_PASS)
|
||||
.unwrap();
|
||||
self.add_system_node(node::NODE, RenderResourcesNode::<Node>::new(true));
|
||||
self.add_node_edge(node::NODE, base_render_graph::node::MAIN_PASS)
|
||||
.unwrap();
|
||||
let mut active_cameras = resources.get_mut::<ActiveCameras>().unwrap();
|
||||
let main_pass_node: &mut PassNode = self.get_node_mut(base_render_graph::node::MAIN_PASS).unwrap();
|
||||
main_pass_node.add_camera(camera::UI_CAMERA);
|
||||
|
||||
@ -9,8 +9,8 @@ layout(set = 2, binding = 0) uniform ColorMaterial_color {
|
||||
};
|
||||
|
||||
# ifdef COLORMATERIAL_TEXTURE
|
||||
layout(set = 3, binding = 0) uniform texture2D ColorMaterial_texture;
|
||||
layout(set = 3, binding = 1) uniform sampler ColorMaterial_texture_sampler;
|
||||
layout(set = 2, binding = 1) uniform texture2D ColorMaterial_texture;
|
||||
layout(set = 2, binding = 2) uniform sampler ColorMaterial_texture_sampler;
|
||||
# endif
|
||||
|
||||
void main() {
|
||||
|
||||
@ -10,15 +10,15 @@ layout(set = 0, binding = 0) uniform UiCamera {
|
||||
mat4 ViewProj;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 0) uniform Quad {
|
||||
vec2 Quad_Position;
|
||||
vec2 Quad_Size;
|
||||
float Quad_ZIndex;
|
||||
layout(set = 1, binding = 0) uniform Transform {
|
||||
mat4 Object;
|
||||
};
|
||||
layout(set = 1, binding = 1) uniform Node_size {
|
||||
vec2 NodeSize;
|
||||
};
|
||||
|
||||
void main() {
|
||||
v_Uv = Vertex_Uv;
|
||||
vec3 position = Vertex_Position * vec3(Quad_Size, 0.0);
|
||||
position = position + vec3(Quad_Position, Quad_ZIndex);
|
||||
gl_Position = ViewProj * vec4(position, 1.0);
|
||||
vec3 position = Vertex_Position * vec3(NodeSize, 0.0);
|
||||
gl_Position = ViewProj * Object * vec4(position, 1.0);
|
||||
}
|
||||
@ -1,74 +1,81 @@
|
||||
use super::Node;
|
||||
use bevy_core::transform::run_on_hierarchy_subworld_mut;
|
||||
use bevy_sprite::Quad;
|
||||
use bevy_transform::prelude::{Children, Parent};
|
||||
use bevy_transform::prelude::{Children, Parent, Translation};
|
||||
use bevy_window::Windows;
|
||||
use glam::Vec2;
|
||||
use legion::{prelude::*, systems::SubWorld};
|
||||
|
||||
pub const UI_Z_STEP: f32 = 0.001;
|
||||
|
||||
pub fn ui_update_system() -> Box<dyn Schedulable> {
|
||||
SystemBuilder::new("ui_update")
|
||||
.read_resource::<Windows>()
|
||||
.with_query(<Read<Node>>::query().filter(!component::<Parent>()))
|
||||
.write_component::<Node>()
|
||||
.write_component::<Quad>()
|
||||
.read_component::<Children>()
|
||||
.build(move |_, world, windows, node_query| {
|
||||
if let Some(window) = windows.get_primary() {
|
||||
let mut window_quad = Quad {
|
||||
size: Vec2::new(window.width as f32, window.height as f32),
|
||||
position: Vec2::new(0.0, 0.0),
|
||||
z_index: 999.0,
|
||||
};
|
||||
for entity in node_query
|
||||
.iter_entities(world)
|
||||
.map(|(e, _)| e)
|
||||
.collect::<Vec<Entity>>()
|
||||
{
|
||||
let result = run_on_hierarchy_subworld_mut(
|
||||
world,
|
||||
entity,
|
||||
window_quad.clone(),
|
||||
&mut update_node_entity,
|
||||
&mut process_child_result,
|
||||
);
|
||||
|
||||
if let Some(result) = result {
|
||||
window_quad.z_index = result.z_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
#[derive(Clone)]
|
||||
pub struct Rect {
|
||||
pub z: f32,
|
||||
pub size: Vec2,
|
||||
}
|
||||
|
||||
fn update_node_entity(world: &mut SubWorld, entity: Entity, parent_quad: Quad) -> Option<Quad> {
|
||||
pub fn ui_update_system(
|
||||
world: &mut SubWorld,
|
||||
windows: Res<Windows>,
|
||||
node_query: &mut Query<(Write<Node>, Write<Translation>)>,
|
||||
_parent_query: &mut Query<Read<Parent>>,
|
||||
_children_query: &mut Query<Read<Children>>,
|
||||
) {
|
||||
let window_size = if let Some(window) = windows.get_primary() {
|
||||
Vec2::new(window.width as f32, window.height as f32)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let orphan_nodes = node_query
|
||||
.iter_entities_mut(world)
|
||||
// TODO: replace this filter with a legion query filter (when SimpleQuery gets support for filters)
|
||||
.filter(|(entity, _)| world.get_component::<Parent>(*entity).is_none())
|
||||
.map(|(e, _)| e)
|
||||
.collect::<Vec<Entity>>();
|
||||
let mut window_rect = Rect {
|
||||
z: 0.0,
|
||||
size: window_size,
|
||||
};
|
||||
|
||||
let mut previous_sibling_result = Some(Rect {
|
||||
z: 999.0,
|
||||
size: window_size,
|
||||
});
|
||||
for entity in orphan_nodes {
|
||||
previous_sibling_result = run_on_hierarchy_subworld_mut(
|
||||
world,
|
||||
entity,
|
||||
Some(&mut window_rect),
|
||||
previous_sibling_result,
|
||||
&mut update_node_entity,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn update_node_entity(world: &mut SubWorld, entity: Entity, parent_rect: Option<&mut Rect>, previous_rect: Option<Rect>) -> Option<Rect> {
|
||||
// TODO: Somehow remove this unsafe
|
||||
unsafe {
|
||||
if let Some(mut node) = world.get_component_mut_unchecked::<Node>(entity) {
|
||||
if let Some(mut quad) = world.get_component_mut_unchecked::<Quad>(entity) {
|
||||
if let Some(mut translation) = world.get_component_mut_unchecked::<Translation>(entity)
|
||||
{
|
||||
let parent_rect = parent_rect.unwrap();
|
||||
let mut z = parent_rect.z;
|
||||
if let Some(previous_rect) = previous_rect {
|
||||
z = previous_rect.z
|
||||
};
|
||||
|
||||
z -= UI_Z_STEP;
|
||||
node.update(
|
||||
&mut quad,
|
||||
parent_quad.size,
|
||||
parent_quad.position,
|
||||
parent_quad.z_index,
|
||||
&mut translation,
|
||||
z - parent_rect.z,
|
||||
parent_rect.size,
|
||||
);
|
||||
return Some(Quad {
|
||||
size: quad.size,
|
||||
position: quad.position - quad.size / 2.0,
|
||||
z_index: quad.z_index - UI_Z_STEP,
|
||||
return Some(Rect {
|
||||
size: node.size,
|
||||
z,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn process_child_result(_parent_result: Quad, child_result: Quad) -> Quad {
|
||||
// "earlier" children are sorted behind "later" children
|
||||
let mut result = child_result.clone();
|
||||
result.z_index -= UI_Z_STEP;
|
||||
result
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
use crate::Node;
|
||||
use bevy_asset::{Assets, Handle};
|
||||
use bevy_render::{
|
||||
draw::{Draw, DrawContext, Drawable},
|
||||
@ -5,9 +6,9 @@ use bevy_render::{
|
||||
texture::Texture,
|
||||
Color,
|
||||
};
|
||||
use bevy_sprite::{ComMut, Quad, TextureAtlas};
|
||||
use bevy_sprite::{ComMut, TextureAtlas};
|
||||
use bevy_text::{DrawableText, Font, FontAtlasSet, TextStyle};
|
||||
use glam::Vec3;
|
||||
use bevy_transform::prelude::Transform;
|
||||
use legion::prelude::{Com, Res, ResMut};
|
||||
|
||||
pub struct Label {
|
||||
@ -44,7 +45,7 @@ impl Label {
|
||||
});
|
||||
// TODO: this call results in one or more TextureAtlases, whose render resources are created in the RENDER_GRAPH_SYSTEMS
|
||||
// stage. That logic runs _before_ the DRAW stage, which means we cant call add_glyphs_to_atlas in the draw stage
|
||||
// without or render resources being a frame behind. Therefore glyph atlasing either needs its own system or the TextureAtlas
|
||||
// without our render resources being a frame behind. Therefore glyph atlasing either needs its own system or the TextureAtlas
|
||||
// resource generation needs to happen AFTER the render graph systems. maybe draw systems should execute within the
|
||||
// render graph so ordering like this can be taken into account? Maybe the RENDER_GRAPH_SYSTEMS stage should be removed entirely
|
||||
// in favor of node.update()? Regardless, in the immediate short term the current approach is fine.
|
||||
@ -66,9 +67,12 @@ impl Label {
|
||||
mut asset_render_resource_bindings: ResMut<AssetRenderResourceBindings>,
|
||||
mut draw: ComMut<Draw>,
|
||||
label: Com<Label>,
|
||||
quad: Com<Quad>,
|
||||
node: Com<Node>,
|
||||
transform: Com<Transform>,
|
||||
) {
|
||||
let position = quad.position - quad.size / 2.0;
|
||||
// let position = transform.0 - quad.size / 2.0;
|
||||
let position = transform.value.w_axis().truncate() - (node.size / 2.0).extend(0.0);
|
||||
|
||||
let mut drawable_text = DrawableText::new(
|
||||
fonts.get(&label.font).unwrap(),
|
||||
font_atlas_sets
|
||||
@ -77,7 +81,7 @@ impl Label {
|
||||
&texture_atlases,
|
||||
&mut render_resource_bindings,
|
||||
&mut asset_render_resource_bindings,
|
||||
Vec3::new(position.x(), position.y(), quad.z_index),
|
||||
position,
|
||||
&label.style,
|
||||
&label.text,
|
||||
);
|
||||
|
||||
@ -73,7 +73,6 @@ fn setup(
|
||||
// texture
|
||||
.add_entity(LabelEntity {
|
||||
node: Node::new(
|
||||
math::vec2(0.0, 0.0),
|
||||
Anchors::TOP_LEFT,
|
||||
Margins::new(0.0, 250.0, 0.0, 60.0),
|
||||
),
|
||||
|
||||
@ -29,7 +29,6 @@ fn setup(command_buffer: &mut CommandBuffer, asset_server: Res<AssetServer>) {
|
||||
// texture
|
||||
.add_entity(LabelEntity {
|
||||
node: Node::new(
|
||||
math::vec2(0.0, 0.0),
|
||||
Anchors::TOP_LEFT,
|
||||
Margins::new(0.0, 250.0, 0.0, 60.0),
|
||||
),
|
||||
|
||||
@ -60,7 +60,6 @@ fn setup(
|
||||
// left vertical fill
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
math::vec2(0.0, 0.0),
|
||||
Anchors::LEFT_FULL,
|
||||
Margins::new(10.0, 200.0, 10.0, 10.0),
|
||||
),
|
||||
@ -70,7 +69,6 @@ fn setup(
|
||||
.add_children(|builder| {
|
||||
builder.add_entity(LabelEntity {
|
||||
node: Node::new(
|
||||
math::vec2(0.0, 0.0),
|
||||
Anchors::TOP_LEFT,
|
||||
Margins::new(10.0, 200.0, 40.0, 10.0),
|
||||
),
|
||||
@ -88,7 +86,6 @@ fn setup(
|
||||
// right vertical fill
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
math::vec2(0.0, 0.0),
|
||||
Anchors::RIGHT_FULL,
|
||||
Margins::new(10.0, 100.0, 100.0, 100.0),
|
||||
),
|
||||
@ -97,7 +94,7 @@ fn setup(
|
||||
})
|
||||
// render order test: reddest in the back, whitest in the front
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
node: Node::positioned(
|
||||
math::vec2(75.0, 60.0),
|
||||
Anchors::CENTER,
|
||||
Margins::new(0.0, 100.0, 0.0, 100.0),
|
||||
@ -106,7 +103,7 @@ fn setup(
|
||||
..Default::default()
|
||||
})
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
node: Node::positioned(
|
||||
math::vec2(50.0, 35.0),
|
||||
Anchors::CENTER,
|
||||
Margins::new(0.0, 100.0, 0.0, 100.0),
|
||||
@ -115,7 +112,7 @@ fn setup(
|
||||
..Default::default()
|
||||
})
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
node: Node::positioned(
|
||||
math::vec2(100.0, 85.0),
|
||||
Anchors::CENTER,
|
||||
Margins::new(0.0, 100.0, 0.0, 100.0),
|
||||
@ -124,7 +121,7 @@ fn setup(
|
||||
..Default::default()
|
||||
})
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
node: Node::positioned(
|
||||
math::vec2(150.0, 135.0),
|
||||
Anchors::CENTER,
|
||||
Margins::new(0.0, 100.0, 0.0, 100.0),
|
||||
@ -134,7 +131,7 @@ fn setup(
|
||||
})
|
||||
// parenting
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
node: Node::positioned(
|
||||
math::vec2(210.0, 0.0),
|
||||
Anchors::BOTTOM_LEFT,
|
||||
Margins::new(0.0, 200.0, 10.0, 210.0),
|
||||
@ -145,7 +142,6 @@ fn setup(
|
||||
.add_children(|builder| {
|
||||
builder.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
math::vec2(0.0, 0.0),
|
||||
Anchors::FULL,
|
||||
Margins::new(20.0, 20.0, 20.0, 20.0),
|
||||
),
|
||||
@ -155,7 +151,7 @@ fn setup(
|
||||
})
|
||||
// alpha test
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
node: Node::positioned(
|
||||
math::vec2(200.0, 185.0),
|
||||
Anchors::CENTER,
|
||||
Margins::new(0.0, 100.0, 0.0, 100.0),
|
||||
@ -166,7 +162,6 @@ fn setup(
|
||||
// texture
|
||||
.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
math::vec2(0.0, 0.0),
|
||||
Anchors::CENTER_TOP,
|
||||
Margins::new(-250.0, 250.0, 510.0 * aspect, 10.0),
|
||||
),
|
||||
|
||||
@ -29,13 +29,14 @@ fn setup(command_buffer: &mut CommandBuffer, mut materials: ResMut<Assets<ColorM
|
||||
let count = 1000;
|
||||
for i in 0..count {
|
||||
// 2d camera
|
||||
let cur = Vec2::new(1.0, 1.0) * 1.0 + prev;
|
||||
let cur = Vec2::new(1.0, 1.0) + prev;
|
||||
builder.add_entity(UiEntity {
|
||||
node: Node::new(
|
||||
math::vec2(75.0, 75.0) + cur,
|
||||
Anchors::new(0.5, 0.5, 0.5, 0.5),
|
||||
Margins::new(0.0, 100.0, 0.0, 100.0),
|
||||
),
|
||||
node: Node {
|
||||
position: Vec2::new(75.0, 75.0) + cur,
|
||||
anchors: Anchors::new(0.5, 0.5, 0.5, 0.5),
|
||||
margins: Margins::new(0.0, 100.0, 0.0, 100.0),
|
||||
..Default::default()
|
||||
},
|
||||
material: materials.add(Color::rgb(0.0 + i as f32 / count as f32, 0.1, 0.1).into()),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
@ -33,7 +33,7 @@ pub use crate::{
|
||||
scene::{Scene, SceneSpawner},
|
||||
sprite::{
|
||||
entity::{SpriteEntity, SpriteSheetEntity},
|
||||
ColorMaterial, Quad, Sprite, TextureAtlas, TextureAtlasSprite,
|
||||
ColorMaterial, Sprite, TextureAtlas, TextureAtlasSprite,
|
||||
},
|
||||
text::{Font, TextStyle},
|
||||
transform::prelude::*,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user