make the mesh stuff work kinda

This commit is contained in:
OMGeeky
2025-04-22 22:16:47 +02:00
parent 7c48e47b17
commit 4044b449e9
2 changed files with 90 additions and 85 deletions

View File

@@ -29,7 +29,7 @@ impl BlockLabelBundle {
} }
} }
} }
fn scale_labels(mut labels: Query<&mut Transform, With<CanvasText>>, canvas: Res<Canvas>) { fn scale_labels(mut labels: Query<&mut Transform, With<Root>>, canvas: Res<Canvas>) {
labels.par_iter_mut().for_each(|mut transform| { labels.par_iter_mut().for_each(|mut transform| {
transform.scale = Vec3::splat(canvas.zoom) * LABEL_SCALING_FACTOR; transform.scale = Vec3::splat(canvas.zoom) * LABEL_SCALING_FACTOR;
}); });

View File

@@ -8,6 +8,7 @@ use serde::Deserialize;
use std::ops::BitOr; use std::ops::BitOr;
pub mod block_label; pub mod block_label;
const CONNECTION_SCALE_FACTOR: f32 = 10.0;
const LABEL_SCALING_FACTOR: f32 = 0.2; const LABEL_SCALING_FACTOR: f32 = 0.2;
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)] #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)]
@@ -17,6 +18,10 @@ enum AppState {
Running, Running,
} }
#[derive(Component)]
#[require(Transform)]
struct Root;
#[derive(Resource)] #[derive(Resource)]
struct BlockDefinitionHandle(Handle<BlockDefinition>); struct BlockDefinitionHandle(Handle<BlockDefinition>);
#[derive(Deserialize, Asset, TypePath, Debug, Clone)] #[derive(Deserialize, Asset, TypePath, Debug, Clone)]
@@ -45,13 +50,6 @@ pub struct ConnectionDefinitionRef {
parent_block: usize, parent_block: usize,
id: usize, id: usize,
} }
#[derive(Bundle, Debug)]
pub struct BlockBundle {
id: Block,
transform: Transform,
global_transform: GlobalTransform,
block_visuals: BlockVisuals,
}
#[derive(Component, Debug)] #[derive(Component, Debug)]
pub struct BlockVisuals { pub struct BlockVisuals {
@@ -63,11 +61,13 @@ pub struct ConnectionReference(Entity);
#[derive(Component, Debug, Copy, Clone)] #[derive(Component, Debug, Copy, Clone)]
pub struct BlockReference(Entity); pub struct BlockReference(Entity);
#[derive(Component, Debug)] #[derive(Component, Debug)]
#[require(Transform, Mesh2d, MeshMaterial2d<ColorMaterial>)]
pub struct Block { pub struct Block {
id: usize, id: usize,
input_count: usize, input_count: usize,
output_count: usize, output_count: usize,
} }
#[derive(Component, Debug)] #[derive(Component, Debug)]
#[require(Transform)] #[require(Transform)]
pub struct Wire { pub struct Wire {
@@ -79,7 +79,7 @@ pub struct InputConnection;
pub struct OutputConnection; pub struct OutputConnection;
#[derive(Component, Debug)] #[derive(Component, Debug)]
#[require(Transform)] #[require(Transform, Mesh2d, MeshMaterial2d<ColorMaterial>)]
pub struct Connection { pub struct Connection {
index: usize, index: usize,
values: ConnectionValues, values: ConnectionValues,
@@ -344,8 +344,7 @@ pub struct LogicSimPlugin;
impl Plugin for LogicSimPlugin { impl Plugin for LogicSimPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app
//hi //
// .insert_resource(get_sample_block())
.add_plugins(JsonAssetPlugin::<BlockDefinition>::new(&["blockdef.json"])) .add_plugins(JsonAssetPlugin::<BlockDefinition>::new(&["blockdef.json"]))
.add_plugins(BlockLabelPlugin) .add_plugins(BlockLabelPlugin)
.add_systems(Startup, setup) .add_systems(Startup, setup)
@@ -355,15 +354,8 @@ impl Plugin for LogicSimPlugin {
Update, Update,
spawn_block_definition_from_asset.run_if(in_state(AppState::Loading)), spawn_block_definition_from_asset.run_if(in_state(AppState::Loading)),
) )
.add_systems( .add_systems(Update, (draw_connections, draw_wires))
Update, .add_systems(Update, update_connection_states);
(
(update_connection_positions, draw_connections).chain(),
render_blocks,
draw_wires,
update_connection_states,
),
);
} }
} }
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
@@ -378,6 +370,8 @@ fn spawn_block_definition_from_asset(
block: Res<BlockDefinitionHandle>, block: Res<BlockDefinitionHandle>,
mut blocks: ResMut<Assets<BlockDefinition>>, mut blocks: ResMut<Assets<BlockDefinition>>,
mut state: ResMut<NextState<AppState>>, mut state: ResMut<NextState<AppState>>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
spawned_blocks: Query<(Entity, &Block)>, spawned_blocks: Query<(Entity, &Block)>,
) { ) {
if let Some(block) = blocks.remove(block.0.id()) { if let Some(block) = blocks.remove(block.0.id()) {
@@ -387,43 +381,64 @@ fn spawn_block_definition_from_asset(
if let Some(e) = spawned_block { if let Some(e) = spawned_block {
commands.entity(e).despawn_recursive(); commands.entity(e).despawn_recursive();
} }
commands.spawn_empty().with_children(|c| { commands.spawn(Root).with_children(|c| {
spawn_block_definition(c, &asset_server, block); spawn_block_definition(c, &asset_server, &mut meshes, &mut materials, block);
}); });
state.set(AppState::Running) state.set(AppState::Running)
} }
} }
fn spawn_block_definition( fn spawn_block_definition(
commands: &mut ChildBuilder, commands: &mut ChildBuilder,
asset_server: &Res<AssetServer>, asset_server: &Res<AssetServer>,
meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<ColorMaterial>>,
block: BlockDefinition, block: BlockDefinition,
) { ) {
let font = asset_server.load("fonts/arcane_nine.otf"); let font = asset_server.load("fonts/arcane_nine.otf");
let mesh = meshes.add(Rectangle::new(block.size.x as f32, block.size.y as f32));
let block_material = materials.add(block.color);
let rectangle = meshes.add(Rectangle::new(
1.0 * CONNECTION_SCALE_FACTOR,
1.0 * CONNECTION_SCALE_FACTOR,
));
let connection_material = materials.add(Color::BLACK);
let text_font = TextFont { let text_font = TextFont {
font, font,
font_size: 100.0, font_size: 100.0,
..default() ..default()
}; };
let mut block_id = commands.spawn(BlockBundle { let block_size = block.size.as_vec2();
id: Block { let input_count = block.inputs.len();
let output_count = block.outputs.len();
let mut block_id = commands.spawn((
Name::new(format!("Block: {}", block.id)),
Block {
id: block.id, id: block.id,
input_count: block.inputs.len(), input_count,
output_count: block.outputs.len(), output_count,
}, },
block_visuals: BlockVisuals { Mesh2d(mesh),
size: block.size, MeshMaterial2d(block_material),
BlockVisuals {
size: block_size.as_ivec2(),
color: block.color, color: block.color,
}, },
global_transform: GlobalTransform::default(), Transform::from_translation(block.pos.extend(0.0)),
transform: Transform::from_translation(block.pos.extend(0.)), ));
});
block_id.with_child(BlockLabelBundle::new(block.name, block.size, text_font)); block_id.with_child(BlockLabelBundle::new(block.name, block.size, text_font));
let id = block_id.id(); let id = block_id.id();
let inputs = block.inputs.iter().enumerate().map(|(i, input)| { let inputs = block.inputs.iter().enumerate().map(|(i, input)| {
let pos =
get_connection_pos_from_index(block_size, input_count, ConnectionPosition::Input, i);
( (
input.id, input.id,
( (
Name::new(format!("Input: {}:{}", i, id)),
Mesh2d(rectangle.clone()),
MeshMaterial2d(connection_material.clone()),
BlockReference(id), BlockReference(id),
Transform::from_translation(pos.extend(2.0)),
InputConnection, InputConnection,
Connection { Connection {
index: i, index: i,
@@ -433,11 +448,17 @@ fn spawn_block_definition(
) )
}); });
let outputs = block.outputs.iter().enumerate().map(|(i, output)| { let outputs = block.outputs.iter().enumerate().map(|(i, output)| {
let pos =
get_connection_pos_from_index(block_size, output_count, ConnectionPosition::Output, i);
( (
output.id, output.id,
( (
Name::new(format!("Output: {}:{}", i, id)),
Mesh2d(rectangle.clone()),
MeshMaterial2d(connection_material.clone()),
BlockReference(id), BlockReference(id),
OutputConnection, OutputConnection,
Transform::from_translation(pos.extend(1.0)),
Connection { Connection {
index: i, index: i,
values: output.value, values: output.value,
@@ -454,9 +475,9 @@ fn spawn_block_definition(
.map(|(id, con)| (id, ConnectionReference(x.spawn(con).id()))) .map(|(id, con)| (id, ConnectionReference(x.spawn(con).id())))
.collect(); .collect();
// let child_blocks = block.inner_blocks.iter().map(|block| { let child_blocks = block.inner_blocks.iter().map(|block| {
// spawn_block_definition(x, asset_server, block.clone()); spawn_block_definition(x, asset_server, meshes, materials, block.clone());
// }); });
let wires = block let wires = block
.wires .wires
@@ -487,57 +508,42 @@ fn spawn_block_definition(
}) })
.collect() .collect()
}) })
.map(|connections| Wire { connections }); .enumerate()
.map(|(i, connections)| (Wire { connections }, Name::new(format!("Wire: {}", i))));
for wire in wires { for wire in wires {
x.spawn(wire); x.spawn(wire);
} }
}); });
} }
#[derive(Debug, Copy, Clone)]
fn render_blocks( enum ConnectionPosition {
blocks: Query<(&BlockVisuals, &Transform)>, Input,
canvas: Res<Canvas>, Output,
mut gizmos: Gizmos,
) {
for (block_visual, transform) in blocks.iter() {
let size = block_visual.size.as_vec2() * canvas.zoom;
let center = transform.translation.xy();
gizmos.rect_2d(center, size, block_visual.color);
}
} }
fn get_connection_pos_from_index(
fn update_connection_positions( size: Vec2,
blocks: Query<(&BlockVisuals, &Block, Option<&InputConnection>)>, count: usize,
mut connections: Query<(&mut Transform, &BlockReference, &Connection)>, anchor: ConnectionPosition,
) { index: usize,
connections ) -> Vec2 {
.iter_mut() let size = size;
.for_each(|(mut transform, block, con)| { let half_size = size / 2.0;
if let Ok((block_visual, block, input)) = blocks.get(block.0) { let top = half_size.y;
let size = block_visual.size.as_vec2(); let left = -half_size.x;
let right = half_size.x;
let half_size = size / 2.0; let pos;
let top = half_size.y; match anchor {
let left = -half_size.x; ConnectionPosition::Input => {
let right = half_size.x; pos = Vec2::new(left, top);
let pos; }
let count; ConnectionPosition::Output => {
if input.is_some() { pos = Vec2::new(right, top);
pos = Vec2::new(left, top); }
count = block.input_count; }
} else { let spacing = size.y / (count + 1) as f32;
pos = Vec2::new(right, top); let pos = pos - Vec2::Y * spacing * (index + 1) as f32;
count = block.output_count; pos
}
let spacing = size.y / (count + 1) as f32;
let pos = pos - Vec2::Y * spacing * (con.index + 1) as f32;
println!("{:?}", pos);
let x = &mut transform;
x.translation = pos.extend(0.0);
}
});
} }
fn draw_connections( fn draw_connections(
@@ -547,22 +553,21 @@ fn draw_connections(
) { ) {
for (connection, transform) in connections.iter() { for (connection, transform) in connections.iter() {
let pos = transform.translation().xy(); let pos = transform.translation().xy();
draw_connection(pos, connection, &canvas, &mut gizmos); draw_connection(pos, connection, transform.scale(), &mut gizmos);
} }
} }
fn draw_connection(pos: Vec2, connection: &Connection, canvas: &Canvas, gizmos: &mut Gizmos) { fn draw_connection(pos: Vec2, connection: &Connection, scale: Vec3, gizmos: &mut Gizmos) {
const CONNECTION_BIT_SIZE: f32 = 10.0; const CONNECTION_BIT_SIZE: f32 = 10.0;
let connection_bit_size = CONNECTION_BIT_SIZE * canvas.zoom; let connection_bit_size = CONNECTION_BIT_SIZE * scale.xy();
let connection_bit_half_size = connection_bit_size * 0.5; let connection_bit_half_size_x = connection_bit_size.x * 0.5;
let size = connection.values.len() as u32; let size = connection.values.len() as u32;
let rows = if size > 8 { 2 } else { 1 }; let rows = if size > 8 { 2 } else { 1 };
let columns = (size as f32 / rows as f32).ceil() as u32; let columns = (size as f32 / rows as f32).ceil() as u32;
let half_offset = Vec2::new(columns as f32, rows as f32) * (connection_bit_size / 2.0); let half_offset = Vec2::new(columns as f32, rows as f32) * (connection_bit_size / 2.0);
let one_size = Vec2::new(connection_bit_size, connection_bit_size); let half_one_size = connection_bit_size / 2.0;
let half_one_size = one_size / 2.0;
'rows: for y in 0..rows { 'rows: for y in 0..rows {
for x in 0..columns { for x in 0..columns {
@@ -575,7 +580,7 @@ fn draw_connection(pos: Vec2, connection: &Connection, canvas: &Canvas, gizmos:
+ half_one_size; + half_one_size;
let value = connection.values.get_by_index(index as usize); let value = connection.values.get_by_index(index as usize);
let color = if value { GREEN } else { RED }; let color = if value { GREEN } else { RED };
gizmos.circle_2d(pos, connection_bit_half_size, color); gizmos.circle_2d(pos, connection_bit_half_size_x, color);
} }
} }
gizmos.rect_2d( gizmos.rect_2d(