crosshair is nice
This commit is contained in:
@@ -163,9 +163,8 @@ fn spawn_kneeboard(
|
|||||||
position: Res<KneeboardPosition>,
|
position: Res<KneeboardPosition>,
|
||||||
) {
|
) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
WebviewSource::new("http://localhost:7878/"), // i want this to become dynamic.... from ui or something
|
WebviewSource::new("http://localhost:7878/MOSRPRPETASPCLORWTSURDEP"),
|
||||||
// WebviewSource::new("https://public.avii.nl/test.html"), // i want this to become dynamic.... from ui or something
|
WebviewSize(Vec2::new(210.0 * 3.5, 279.0 * 3.5)),
|
||||||
WebviewSize(Vec2::new(210.0 * 3.5, 279.0 * 3.5)), // this can also be dynamic... kinda like rotating phone
|
|
||||||
Mesh3d(meshes.add(Cuboid::new(0.210, 0.279, 0.01))),
|
Mesh3d(meshes.add(Cuboid::new(0.210, 0.279, 0.01))),
|
||||||
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial {
|
MeshMaterial3d(materials.add(WebviewExtendStandardMaterial {
|
||||||
base: StandardMaterial {
|
base: StandardMaterial {
|
||||||
|
|||||||
152
src/main.rs
152
src/main.rs
@@ -30,9 +30,10 @@ fn main() {
|
|||||||
.add_plugins(KneeboardPlugin)
|
.add_plugins(KneeboardPlugin)
|
||||||
.insert_resource(ClearColor(Color::NONE))
|
.insert_resource(ClearColor(Color::NONE))
|
||||||
.insert_resource(LastPenPos(None))
|
.insert_resource(LastPenPos(None))
|
||||||
|
.insert_resource(PenColor(css::BLACK.into()))
|
||||||
.insert_resource(PenSize(5.0))
|
.insert_resource(PenSize(5.0))
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
.add_systems(Update, (cursor, draw, plot).chain())
|
.add_systems(Update, (color_changer, cursor, draw, plot).chain())
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,14 +43,17 @@ struct MyProcGenImage(Handle<Image>);
|
|||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct PenSize(f32);
|
struct PenSize(f32);
|
||||||
|
|
||||||
const IMAGE_WIDTH: u32 = (210.0 * 3.5) as u32;
|
#[derive(Resource)]
|
||||||
const IMAGE_HEIGHT: u32 = (279.0 * 3.5) as u32;
|
struct PenColor(Color);
|
||||||
|
|
||||||
|
const IMAGE_WIDTH: i32 = (210.0 * 3.5) as i32;
|
||||||
|
const IMAGE_HEIGHT: i32 = (279.0 * 3.5) as i32;
|
||||||
|
|
||||||
fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
|
fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
|
||||||
let image = Image::new_fill(
|
let image = Image::new_fill(
|
||||||
Extent3d {
|
Extent3d {
|
||||||
width: IMAGE_WIDTH,
|
width: IMAGE_WIDTH as u32,
|
||||||
height: IMAGE_HEIGHT,
|
height: IMAGE_HEIGHT as u32,
|
||||||
depth_or_array_layers: 1,
|
depth_or_array_layers: 1,
|
||||||
},
|
},
|
||||||
TextureDimension::D2,
|
TextureDimension::D2,
|
||||||
@@ -74,10 +78,18 @@ fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
|
|||||||
struct CursorBuffer([u8; IMAGE_WIDTH as usize * IMAGE_HEIGHT as usize * 4]);
|
struct CursorBuffer([u8; IMAGE_WIDTH as usize * IMAGE_HEIGHT as usize * 4]);
|
||||||
|
|
||||||
impl Drawing for CursorBuffer {
|
impl Drawing for CursorBuffer {
|
||||||
fn set_color_at(&mut self, x: u32, y: u32, color: Color) {
|
fn set_color_at(&mut self, x: i32, y: i32, color: Color) {
|
||||||
|
if !(0..=IMAGE_WIDTH).contains(&x) || !(0..=IMAGE_HEIGHT).contains(&y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let index = ((x + (IMAGE_WIDTH * y)) * 4) as usize;
|
let index = ((x + (IMAGE_WIDTH * y)) * 4) as usize;
|
||||||
let srgba = Srgba::from(color);
|
let srgba = Srgba::from(color);
|
||||||
|
|
||||||
|
if index >= self.0.len() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.0[index] = (srgba.red * u8::MAX as f32) as u8;
|
self.0[index] = (srgba.red * u8::MAX as f32) as u8;
|
||||||
self.0[index + 1] = (srgba.green * u8::MAX as f32) as u8;
|
self.0[index + 1] = (srgba.green * u8::MAX as f32) as u8;
|
||||||
self.0[index + 2] = (srgba.blue * u8::MAX as f32) as u8;
|
self.0[index + 2] = (srgba.blue * u8::MAX as f32) as u8;
|
||||||
@@ -93,13 +105,21 @@ impl Drawing for CursorBuffer {
|
|||||||
struct DrawingBuffer([u8; IMAGE_WIDTH as usize * IMAGE_HEIGHT as usize * 4]);
|
struct DrawingBuffer([u8; IMAGE_WIDTH as usize * IMAGE_HEIGHT as usize * 4]);
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct LastPenPos(pub Option<(u32, u32)>);
|
pub struct LastPenPos(pub Option<(i32, i32)>);
|
||||||
|
|
||||||
impl Drawing for DrawingBuffer {
|
impl Drawing for DrawingBuffer {
|
||||||
fn set_color_at(&mut self, x: u32, y: u32, color: Color) {
|
fn set_color_at(&mut self, x: i32, y: i32, color: Color) {
|
||||||
|
if !(0..=IMAGE_WIDTH).contains(&x) || !(0..=IMAGE_HEIGHT).contains(&y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let index = ((x + (IMAGE_WIDTH * y)) * 4) as usize;
|
let index = ((x + (IMAGE_WIDTH * y)) * 4) as usize;
|
||||||
let srgba = Srgba::from(color);
|
let srgba = Srgba::from(color);
|
||||||
|
|
||||||
|
if index >= self.0.len() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.0[index] = (srgba.red * u8::MAX as f32) as u8;
|
self.0[index] = (srgba.red * u8::MAX as f32) as u8;
|
||||||
self.0[index + 1] = (srgba.green * u8::MAX as f32) as u8;
|
self.0[index + 1] = (srgba.green * u8::MAX as f32) as u8;
|
||||||
self.0[index + 2] = (srgba.blue * u8::MAX as f32) as u8;
|
self.0[index + 2] = (srgba.blue * u8::MAX as f32) as u8;
|
||||||
@@ -111,67 +131,103 @@ impl Drawing for DrawingBuffer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn color_changer(mut pen_color: ResMut<PenColor>, mut pen_buttons: MessageReader<PenButtons>) {
|
||||||
|
let Some(buttons) = pen_buttons.read().next() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
pen_color.0 = css::BLACK.into();
|
||||||
|
|
||||||
|
if (buttons.state & 2) == 2 {
|
||||||
|
let mut t = LinearRgba::from(pen_color.0);
|
||||||
|
t.alpha = 0.0;
|
||||||
|
pen_color.0 = t.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buttons.state & 4) == 4 {
|
||||||
|
let mut t = LinearRgba::from(css::DARK_BLUE);
|
||||||
|
t.alpha = 0.5;
|
||||||
|
pen_color.0 = t.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn cursor(
|
fn cursor(
|
||||||
|
pen_color: Res<PenColor>,
|
||||||
mut buffer: ResMut<CursorBuffer>,
|
mut buffer: ResMut<CursorBuffer>,
|
||||||
mut pen_size: ResMut<PenSize>,
|
mut pen_size: ResMut<PenSize>,
|
||||||
mut pen_buttons: MessageReader<PenButtons>,
|
mut pen_buttons: MessageReader<PenButtons>,
|
||||||
mut pen_position: MessageReader<PenPosition>,
|
mut pen_position: MessageReader<PenPosition>,
|
||||||
mut pen_pressure: MessageReader<PenPressure>,
|
mut pen_pressure: MessageReader<PenPressure>,
|
||||||
) {
|
) {
|
||||||
let mut size: f32 = 4.0;
|
let mut size: f32 = 1.0;
|
||||||
|
let mut offset = 20.0;
|
||||||
|
|
||||||
for penpres in pen_pressure.read() {
|
let c = pen_color.0;
|
||||||
size += penpres.pressure * 2.;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(buttons) = pen_buttons.read().next()
|
if let Some(buttons) = pen_buttons.read().next()
|
||||||
&& (buttons.state & 2 == 2)
|
&& (buttons.state & 2 == 2)
|
||||||
{
|
{
|
||||||
size = 40.;
|
offset *= 4.;
|
||||||
};
|
};
|
||||||
|
|
||||||
pen_size.0 = size;
|
for penpres in pen_pressure.read() {
|
||||||
|
// this needs log scaling
|
||||||
|
|
||||||
let color = css::BLACK.into();
|
let _in = penpres.pressure;
|
||||||
|
let _out = penpres.pressure.powi(4);
|
||||||
|
|
||||||
|
size *= 1. + (_out * offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
pen_size.0 = size.clamp(1.0, 200.0);
|
||||||
|
let s = pen_size.0 as i32;
|
||||||
|
let b = css::BLACK.into();
|
||||||
|
|
||||||
|
let cs = 10;
|
||||||
|
let cd = 3;
|
||||||
|
|
||||||
for penpos in pen_position.read() {
|
for penpos in pen_position.read() {
|
||||||
let x = (penpos.position.x * (IMAGE_WIDTH as f32)) as i32;
|
let x = (penpos.position.x * (IMAGE_WIDTH as f32)) as i32;
|
||||||
let y = (penpos.position.y * (IMAGE_HEIGHT as f32)) as i32;
|
let y = (penpos.position.y * (IMAGE_HEIGHT as f32)) as i32;
|
||||||
|
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
draw_circle(&mut buffer, x, y, (size) as i32, 3.0, color);
|
draw_line(&mut buffer, x - (cs + cd) - s, y, x - (cd) - s, y, 4.0, b);
|
||||||
|
draw_line(&mut buffer, x - (cs + cd) - s, y, x - (cd) - s, y, 1.0, c);
|
||||||
|
draw_line(&mut buffer, x + (cd) + s, y, x + (cs + cd) + s, y, 4.0, b);
|
||||||
|
draw_line(&mut buffer, x + (cd) + s, y, x + (cs + cd) + s, y, 1.0, c);
|
||||||
|
|
||||||
|
draw_line(&mut buffer, x, y - (cs + cd) - s, x, y - (cd) - s, 4.0, b);
|
||||||
|
draw_line(&mut buffer, x, y - (cs + cd) - s, x, y - (cd) - s, 1.0, c);
|
||||||
|
draw_line(&mut buffer, x, y + (cs + cd) + s, x, y + (cd) + s, 4.0, b);
|
||||||
|
draw_line(&mut buffer, x, y + (cs + cd) + s, x, y + (cd) + s, 1.0, c);
|
||||||
|
|
||||||
|
draw_filled_circle(&mut buffer, x, y, (pen_size.0 / 2.) as i32, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
pen_size: Res<PenSize>,
|
pen_size: Res<PenSize>,
|
||||||
|
pen_color: Res<PenColor>,
|
||||||
mut lastloc: ResMut<LastPenPos>,
|
mut lastloc: ResMut<LastPenPos>,
|
||||||
mut buffer: ResMut<DrawingBuffer>,
|
mut buffer: ResMut<DrawingBuffer>,
|
||||||
mut pen_buttons: MessageReader<PenButtons>,
|
mut pen_buttons: MessageReader<PenButtons>,
|
||||||
mut pen_position: MessageReader<PenPosition>,
|
mut pen_position: MessageReader<PenPosition>,
|
||||||
) {
|
) {
|
||||||
let mut color = css::TURQUOISE.into();
|
let Some(buttons) = pen_buttons.read().next() else {
|
||||||
let mut is_down = false;
|
return;
|
||||||
|
|
||||||
if let Some(buttons) = pen_buttons.read().next() {
|
|
||||||
is_down = buttons.state & 1 == 1;
|
|
||||||
if buttons.state >= 2 {
|
|
||||||
color = Color::linear_rgba(1.0, 1.0, 1.0, 0.0);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for penpos in pen_position.read() {
|
for penpos in pen_position.read() {
|
||||||
let x = (penpos.position.x * (IMAGE_WIDTH as f32)) as u32;
|
let x = (penpos.position.x * (IMAGE_WIDTH as f32)) as i32;
|
||||||
let y = (penpos.position.y * (IMAGE_HEIGHT as f32)) as u32;
|
let y = (penpos.position.y * (IMAGE_HEIGHT as f32)) as i32;
|
||||||
|
|
||||||
let Some(ll) = lastloc.0 else {
|
let Some(ll) = lastloc.0 else {
|
||||||
lastloc.0 = Some((x, y));
|
lastloc.0 = Some((x, y));
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_down {
|
if buttons.state & 1 == 1 {
|
||||||
let c = if color.alpha() == 0.0 { 2.0 } else { 1.0 };
|
draw_line(&mut buffer, ll.0, ll.1, x, y, pen_size.0, pen_color.0);
|
||||||
draw_line(&mut buffer, ll.0, ll.1, x, y, pen_size.0 * c, color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lastloc.0 = Some((x, y));
|
lastloc.0 = Some((x, y));
|
||||||
@@ -179,21 +235,21 @@ fn draw(
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait Drawing {
|
trait Drawing {
|
||||||
fn set_color_at(&mut self, px: u32, py: u32, color: Color);
|
fn set_color_at(&mut self, px: i32, py: i32, color: Color);
|
||||||
fn clear(&mut self);
|
fn clear(&mut self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_line(
|
fn draw_line<T: Drawing + Resource>(
|
||||||
buffer: &mut ResMut<DrawingBuffer>,
|
buffer: &mut ResMut<T>,
|
||||||
x1: u32,
|
x1: i32,
|
||||||
y1: u32,
|
y1: i32,
|
||||||
x2: u32,
|
x2: i32,
|
||||||
y2: u32,
|
y2: i32,
|
||||||
thickness: f32,
|
thickness: f32,
|
||||||
color: Color,
|
color: Color,
|
||||||
) {
|
) {
|
||||||
let (mut x0, mut y0) = (x1 as i32, y1 as i32);
|
let (mut x0, mut y0) = (x1, y1);
|
||||||
let (x1, y1) = (x2 as i32, y2 as i32);
|
let (x1, y1) = (x2, y2);
|
||||||
|
|
||||||
let dx = (x1 - x0).abs();
|
let dx = (x1 - x0).abs();
|
||||||
let dy = -(y1 - y0).abs();
|
let dy = -(y1 - y0).abs();
|
||||||
@@ -255,7 +311,7 @@ fn draw_filled_circle<T: Drawing + Resource>(
|
|||||||
|
|
||||||
for x in start_x..=end_x {
|
for x in start_x..=end_x {
|
||||||
if x >= 0 {
|
if x >= 0 {
|
||||||
buffer.set_color_at(x as u32, y as u32, color);
|
buffer.set_color_at(x, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -310,21 +366,21 @@ fn draw_circle<T: Drawing + Resource>(
|
|||||||
// left segment
|
// left segment
|
||||||
for x in left_outer..left_inner {
|
for x in left_outer..left_inner {
|
||||||
if x >= 0 {
|
if x >= 0 {
|
||||||
buffer.set_color_at(x as u32, y as u32, color);
|
buffer.set_color_at(x, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// right segment
|
// right segment
|
||||||
for x in (right_inner + 1)..=right_outer {
|
for x in (right_inner + 1)..=right_outer {
|
||||||
if x >= 0 {
|
if x >= 0 {
|
||||||
buffer.set_color_at(x as u32, y as u32, color);
|
buffer.set_color_at(x, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// fully filled span (very thin or small radius)
|
// fully filled span (very thin or small radius)
|
||||||
for x in left_outer..=right_outer {
|
for x in left_outer..=right_outer {
|
||||||
if x >= 0 {
|
if x >= 0 {
|
||||||
buffer.set_color_at(x as u32, y as u32, color);
|
buffer.set_color_at(x, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,8 +399,8 @@ fn plot(
|
|||||||
image.clear(&[0, 0, 0, 0]);
|
image.clear(&[0, 0, 0, 0]);
|
||||||
|
|
||||||
for (i, c) in buffer.0.chunks(4).enumerate() {
|
for (i, c) in buffer.0.chunks(4).enumerate() {
|
||||||
let x = i as u32 % IMAGE_WIDTH;
|
let x = i as i32 % IMAGE_WIDTH;
|
||||||
let y = i as u32 / IMAGE_WIDTH;
|
let y = i as i32 / IMAGE_WIDTH;
|
||||||
|
|
||||||
let red: u8 = c[0];
|
let red: u8 = c[0];
|
||||||
let green = c[1];
|
let green = c[1];
|
||||||
@@ -353,13 +409,13 @@ fn plot(
|
|||||||
|
|
||||||
if alpha > 0 {
|
if alpha > 0 {
|
||||||
let color = Color::srgba_u8(red, green, blue, alpha);
|
let color = Color::srgba_u8(red, green, blue, alpha);
|
||||||
image.set_color_at(x, y, color).unwrap();
|
image.set_color_at(x as u32, y as u32, color).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, c) in cursor.0.chunks(4).enumerate() {
|
for (i, c) in cursor.0.chunks(4).enumerate() {
|
||||||
let x = i as u32 % IMAGE_WIDTH;
|
let x = i as i32 % IMAGE_WIDTH;
|
||||||
let y = i as u32 / IMAGE_WIDTH;
|
let y = i as i32 / IMAGE_WIDTH;
|
||||||
|
|
||||||
let red: u8 = c[0];
|
let red: u8 = c[0];
|
||||||
let green = c[1];
|
let green = c[1];
|
||||||
@@ -368,7 +424,7 @@ fn plot(
|
|||||||
|
|
||||||
if alpha > 0 {
|
if alpha > 0 {
|
||||||
let color = Color::srgba_u8(red, green, blue, alpha);
|
let color = Color::srgba_u8(red, green, blue, alpha);
|
||||||
image.set_color_at(x, y, color).unwrap();
|
image.set_color_at(x as u32, y as u32, color).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user