aboutsummaryrefslogtreecommitdiff
path: root/web/pw-frontend/planetwars-rs
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2021-12-29 21:24:57 +0100
committerIlion Beyst <ilion.beyst@gmail.com>2021-12-29 21:25:29 +0100
commit0c6d978442b244ca3f29c1ffdd44b5007ae7ad93 (patch)
treebaae5fa459a49ecd362e548e0649e2f58c669a70 /web/pw-frontend/planetwars-rs
parent3eeaab6cec70e7a06a99a1ac2662974f71064bee (diff)
downloadplanetwars.dev-0c6d978442b244ca3f29c1ffdd44b5007ae7ad93.tar.xz
planetwars.dev-0c6d978442b244ca3f29c1ffdd44b5007ae7ad93.zip
separate out visualizer library
Diffstat (limited to 'web/pw-frontend/planetwars-rs')
-rw-r--r--web/pw-frontend/planetwars-rs/.gitignore2
-rw-r--r--web/pw-frontend/planetwars-rs/Cargo.toml44
-rw-r--r--web/pw-frontend/planetwars-rs/src/lib.rs373
-rw-r--r--web/pw-frontend/planetwars-rs/src/types.rs45
-rw-r--r--web/pw-frontend/planetwars-rs/src/utils.rs65
5 files changed, 0 insertions, 529 deletions
diff --git a/web/pw-frontend/planetwars-rs/.gitignore b/web/pw-frontend/planetwars-rs/.gitignore
deleted file mode 100644
index a04eea2..0000000
--- a/web/pw-frontend/planetwars-rs/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-pkg/**
-target/**
diff --git a/web/pw-frontend/planetwars-rs/Cargo.toml b/web/pw-frontend/planetwars-rs/Cargo.toml
deleted file mode 100644
index a5dc949..0000000
--- a/web/pw-frontend/planetwars-rs/Cargo.toml
+++ /dev/null
@@ -1,44 +0,0 @@
-[package]
-name = "planetwars-rs"
-version = "0.1.0"
-authors = ["ajuvercr <arthur.vercruysse@ugent.be>"]
-edition = "2018"
-
-[package.metadata.wasm-pack.profile.release]
-wasm-opt = ["-Oz", "--enable-mutable-globals"]
-
-[lib]
-crate-type = ["cdylib", "rlib"]
-
-[features]
-default = ["console_error_panic_hook"]
-
-[dependencies]
-wasm-bindgen = "0.2.63"
-
-# The `console_error_panic_hook` crate provides better debugging of panics by
-# logging them with `console.error`. This is great for development, but requires
-# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
-# code size when deploying.
-console_error_panic_hook = { version = "0.1.6", optional = true }
-
-# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
-# compared to the default allocator's ~10K. It is slower than the default
-# allocator, however.
-#
-# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
-wee_alloc = { version = "0.4.5", optional = true }
-serde = "1.0.100"
-serde_derive = "1.0.100"
-serde_json = "1.0"
-octoon-math = "0.1.7"
-voronoi = "0.1.4"
-
-[dev-dependencies]
-wasm-bindgen-test = "0.3.13"
-
-[profile.release]
-# Tell `rustc` to optimize for small code size.
-opt-level = "s"
-
-[workspace] \ No newline at end of file
diff --git a/web/pw-frontend/planetwars-rs/src/lib.rs b/web/pw-frontend/planetwars-rs/src/lib.rs
deleted file mode 100644
index f2ba7e1..0000000
--- a/web/pw-frontend/planetwars-rs/src/lib.rs
+++ /dev/null
@@ -1,373 +0,0 @@
-extern crate serde;
-#[macro_use]
-extern crate serde_derive;
-extern crate octoon_math;
-extern crate serde_json;
-extern crate voronoi;
-
-use octoon_math::Mat3;
-use voronoi::{make_polygons, voronoi, Point};
-
-mod types;
-mod utils;
-
-use std::collections::HashMap;
-use wasm_bindgen::prelude::*;
-
-macro_rules! console_log {
- // Note that this is using the `log` function imported above during
- // `bare_bones`
- ($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
-}
-
-// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
-// allocator.
-#[cfg(feature = "wee_alloc")]
-#[global_allocator]
-static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
-
-#[derive(Debug, Clone)]
-pub struct Circle {
- r: f32,
- x: f32,
- y: f32,
- a0: f32,
- ad: f32,
- distance: usize,
-}
-
-use std::f32::consts::PI;
-fn spr(from: f32) -> f32 {
- let pi2 = PI * 2.;
- ((from % pi2) + pi2) % pi2
-}
-
-impl Circle {
- pub fn new(p1: &types::Planet, p2: &types::Planet) -> Self {
- let x1 = p1.x;
- let y1 = p1.y;
- let x2 = p2.x;
- let y2 = p2.y;
-
- // Distance between planets
- let q = ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt();
- // Center of between planets
- let x3 = (x1 + x2) / 2.0;
- let y3 = (y1 + y2) / 2.0;
-
- // Radius of circle
- let r = q * 1.0;
-
- // Center of circle
- let x = x3 + (r.powi(2) - (q / 2.0).powi(2)).sqrt() * (y1 - y2) / q;
- let y = y3 + (r.powi(2) - (q / 2.0).powi(2)).sqrt() * (x2 - x1) / q;
- // console_log!("{},{} -> {},{} ({},{} r={})", x1, y1, x2, y2, x, y, r);
-
- let a0 = spr((y - y1).atan2(x - x1));
- let a2 = spr((y - y2).atan2(x - x2));
-
- let mut ad = spr(a0 - a2);
- if ad > PI {
- ad = spr(a2 - a0);
- }
- // console_log!("a1 {} a2 {} ad {}", a0/PI * 180.0, a2/PI * 180.0, ad/PI*180.0);
-
- let distance = q.ceil() as usize + 1;
- Self {
- r,
- x,
- y,
- a0,
- ad,
- distance,
- }
- }
-
- pub fn get_for_remaining(&self, remaining: usize) -> ((Mat3<f32>, f32), (Mat3<f32>, f32)) {
- (
- self.get_remaining(remaining),
- self.get_remaining((remaining + 1).min(self.distance - 1)),
- )
- }
-
- fn get_remaining(&self, remaining: usize) -> (Mat3<f32>, f32) {
- let alpha = self.a0 + (1.0 - (remaining as f32 / self.distance as f32)) * self.ad;
-
- let cos = alpha.cos();
- let sin = alpha.sin();
- (
- Mat3::new(
- 0.3,
- 0.0,
- 0.0,
- 0.0,
- 0.3,
- 0.0,
- -self.x + cos * self.r,
- -self.y + sin * self.r,
- 0.3,
- ),
- alpha,
- )
- }
-}
-
-fn create_voronoi(planets: &Vec<types::Planet>, bbox: f32) -> (Vec<f32>, Vec<usize>) {
- let mut verts: Vec<[f32; 2]> = planets.iter().map(|p| [p.x, p.y]).collect();
- let mut ids = Vec::new();
-
- let vor_points = planets
- .iter()
- .map(|p| Point::new(p.x as f64, p.y as f64))
- .collect();
-
- let vor = voronoi(vor_points, bbox as f64);
- let vor = make_polygons(&vor);
-
- for poly in vor.iter() {
- // Get planet index for planet that is inside this poligon
- let idx = 0;
-
- let mut prev = ids.len() + poly.len() - 1;
- for p in poly.iter() {
- let now = verts.len();
- verts.push([p.x.0 as f32, p.y.0 as f32]);
-
- ids.push(idx);
- ids.push(now);
- ids.push(prev);
- prev = now;
- }
- }
-
- (verts.concat(), ids)
-}
-
-#[wasm_bindgen]
-pub struct Game {
- states: Vec<types::State>,
- turn: usize,
-
- planet_map: HashMap<(String, String), Circle>,
-
- /* put extra shit here */
- view_box: Vec<f32>,
-
- planets: Vec<f32>,
- planet_ships: Vec<usize>,
-
- ship_locations: Vec<f32>,
- ship_label_locations: Vec<f32>,
- ship_colours: Vec<f32>,
- ship_counts: Vec<usize>,
-
- current_planet_colours: Vec<f32>,
-
- voronoi_vertices: Vec<f32>,
- voronoi_colors: Vec<f32>,
- voronoi_indices: Vec<usize>,
-}
-
-#[wasm_bindgen]
-impl Game {
- pub fn new(file: &str) -> Self {
- utils::set_panic_hook();
-
- // First line is fucked but we just filter out things that cannot parse
- let states: Vec<types::State> = file
- .split("\n")
- .filter_map(|line| serde_json::from_str(line).ok())
- .collect();
-
- let mut planet_map = HashMap::new();
-
- // Iterator?
- for p1 in states[0].planets.iter() {
- for p2 in states[0].planets.iter() {
- planet_map.insert((p1.name.clone(), p2.name.clone()), Circle::new(&p1, &p2));
- }
- }
- let view_box = utils::caclulate_viewbox(&states[0].planets);
-
- let (voronoi_vertices, voronoi_indices) =
- create_voronoi(&states[0].planets, view_box[2].max(view_box[3]));
-
- let voronoi_colors: Vec<f32> = voronoi_indices
- .iter()
- .map(|_| [0.0, 0.0, 0.0])
- .collect::<Vec<[f32; 3]>>()
- .concat(); // Init these colours on black
-
- Self {
- planets: utils::get_planets(&states[0].planets, 2.0),
- planet_ships: Vec::new(),
- view_box,
-
- planet_map,
- turn: 0,
- states,
- ship_locations: Vec::new(),
- ship_label_locations: Vec::new(),
- ship_colours: Vec::new(),
- ship_counts: Vec::new(),
- current_planet_colours: Vec::new(),
-
- voronoi_vertices,
- voronoi_indices,
- voronoi_colors,
- }
- }
-
- pub fn push_state(&mut self, state_str: &str) {
- if let Ok(state) = serde_json::from_str(state_str) {
- self.states.push(state);
- }
- }
-
- pub fn get_viewbox(&self) -> Vec<f32> {
- self.view_box.clone()
- }
-
- pub fn get_planets(&self) -> Vec<f32> {
- self.planets.clone()
- }
-
- pub fn get_planet_ships(&self) -> Vec<usize> {
- self.planet_ships.clone()
- }
-
- pub fn get_planet_colors(&self) -> Vec<f32> {
- self.current_planet_colours.clone()
- }
-
- pub fn turn_count(&self) -> usize {
- self.states.len()
- }
-
- pub fn update_turn(&mut self, turn: usize) -> usize {
- self.turn = turn.min(self.states.len() - 1);
-
- self.update_planet_ships();
- self.update_planet_colours();
- self.update_voronoi_colors();
- self.update_ship_locations();
- self.update_ship_counts();
-
- self.turn
- }
-
- fn update_planet_ships(&mut self) {
- self.planet_ships = self.states[self.turn]
- .planets
- .iter()
- .map(|p| p.ship_count as usize)
- .collect();
- }
-
- fn update_voronoi_colors(&mut self) {
- for (i, p) in self.states[self.turn].planets.iter().enumerate() {
- let color = utils::COLORS[p.owner.unwrap_or(0) as usize % utils::COLORS.len()];
- self.voronoi_colors[i * 3 + 0] = color[0];
- self.voronoi_colors[i * 3 + 1] = color[1];
- self.voronoi_colors[i * 3 + 2] = color[2];
- }
- }
-
- fn update_planet_colours(&mut self) {
- let mut new_vec: Vec<[f32; 3]> = Vec::new();
- let planets_now = self.states[self.turn].planets.iter();
- let planets_later = self.states[(self.turn + 1).min(self.states.len() - 1)]
- .planets
- .iter();
-
- for (p1, p2) in planets_now.zip(planets_later) {
- new_vec
- .push(utils::COLORS[p1.owner.unwrap_or(0) as usize % utils::COLORS.len()].into());
- new_vec
- .push(utils::COLORS[p2.owner.unwrap_or(0) as usize % utils::COLORS.len()].into());
- }
-
- self.current_planet_colours = new_vec.concat::<f32>();
- }
-
- fn update_ship_locations(&mut self) {
- let mut new_sl = Vec::new();
- let mut new_sll = Vec::new();
-
- let t = Mat3::new(0.2, 0., 0., 0., 0.2, 0.0, 0., -0.5, 0.2);
-
- for ship in self.states[self.turn].expeditions.iter() {
- let ((o1, a1), (o2, a2)) = self
- .planet_map
- .get(&(ship.origin.clone(), ship.destination.clone()))
- .unwrap()
- .get_for_remaining(ship.turns_remaining as usize);
- new_sl.push((o1 * Mat3::rotate_z(a1)).to_array());
- new_sl.push((o2 * Mat3::rotate_z(a2)).to_array());
-
- new_sll.push((o1 + t).to_array());
- new_sll.push((o2 + t).to_array());
- }
-
- self.ship_locations = new_sl.concat();
- self.ship_label_locations = new_sll.concat();
-
- self.ship_colours = self.states[self.turn]
- .expeditions
- .iter()
- .map(|s| utils::COLORS[s.owner as usize % utils::COLORS.len()])
- .collect::<Vec<[f32; 3]>>()
- .concat();
- }
-
- fn update_ship_counts(&mut self) {
- self.ship_counts = self.states[self.turn]
- .expeditions
- .iter()
- .map(|s| s.ship_count as usize)
- .collect();
- }
-
- pub fn get_max_ships(&self) -> usize {
- self.states
- .iter()
- .map(|s| s.expeditions.len())
- .max()
- .unwrap()
- }
-
- pub fn get_ship_locations(&self) -> Vec<f32> {
- self.ship_locations.clone()
- }
-
- pub fn get_ship_label_locations(&self) -> Vec<f32> {
- self.ship_label_locations.clone()
- }
-
- pub fn get_ship_colours(&self) -> Vec<f32> {
- self.ship_colours.clone()
- }
-
- pub fn get_ship_counts(&self) -> Vec<usize> {
- self.ship_counts.clone()
- }
-
- pub fn get_voronoi_verts(&self) -> Vec<f32> {
- self.voronoi_vertices.clone()
- }
-
- pub fn get_voronoi_colours(&self) -> Vec<f32> {
- self.voronoi_colors.clone()
- }
-
- pub fn get_voronoi_inds(&self) -> Vec<usize> {
- self.voronoi_indices.clone()
- }
-}
-
-#[wasm_bindgen]
-extern "C" {
- fn alert(s: &str);
- #[wasm_bindgen(js_namespace = console)]
- fn log(s: &str);
-}
diff --git a/web/pw-frontend/planetwars-rs/src/types.rs b/web/pw-frontend/planetwars-rs/src/types.rs
deleted file mode 100644
index 2d7d8c0..0000000
--- a/web/pw-frontend/planetwars-rs/src/types.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct Expedition {
- pub id: u64,
- pub ship_count: u64,
- pub origin: String,
- pub destination: String,
- pub owner: u64,
- pub turns_remaining: u64,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct Planet {
- pub ship_count: u64,
- pub x: f32,
- pub y: f32,
- pub owner: Option<u32>,
- pub name: String,
-}
-
-use std::hash::{Hash, Hasher};
-use std::mem;
-
-impl Hash for Planet {
- fn hash<H: Hasher>(&self, state: &mut H) {
- unsafe {
- let x: u32 = mem::transmute_copy(&self.x);
- let y: u32 = mem::transmute_copy(&self.y);
- state.write_u32(x);
- state.write_u32(y);
- }
- }
-}
-
-impl PartialEq for Planet {
- fn eq(&self, other: &Self) -> bool {
- (self.x - other.x).abs() < 0.0001 && (self.y - other.y).abs() < 0.0001
- }
-}
-impl Eq for Planet {}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct State {
- pub planets: Vec<Planet>,
- pub expeditions: Vec<Expedition>,
-}
diff --git a/web/pw-frontend/planetwars-rs/src/utils.rs b/web/pw-frontend/planetwars-rs/src/utils.rs
deleted file mode 100644
index a903912..0000000
--- a/web/pw-frontend/planetwars-rs/src/utils.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-pub fn set_panic_hook() {
- // When the `console_error_panic_hook` feature is enabled, we can call the
- // `set_panic_hook` function at least once during initialization, and then
- // we will get better error messages if our code ever panics.
- //
- // For more details see
- // https://github.com/rustwasm/console_error_panic_hook#readme
- #[cfg(feature = "console_error_panic_hook")]
- console_error_panic_hook::set_once();
-}
-
-/// this is total extra, so it the planet viewbox is like 100px wide, it will now be in total 110 pixels wide
-static VIEWBOX_SCALE: f32 = 0.1;
-
-pub static COLORS: [[f32; 3]; 10] = [
- [0.5, 0.5, 0.5],
- [1.0, 0.50, 0.0], // #FF8000
- [0.0, 0.50, 1.0], // #0080ff
- [1.0, 0.4, 0.58], // #FF6693
- [0.24, 0.79, 0.33], // #3fcb55
- [0.79, 0.76, 0.24], // #cbc33f
- [0.81, 0.25, 0.91], // #cf40e9
- [0.94, 0.32, 0.32], // #FF3F0D
- [0.11, 0.93, 0.94], // #1beef0
- [0.05, 0.77, 1.0], // #0DC5FF
-];
-
-use super::types;
-
-pub fn caclulate_viewbox(planets: &Vec<types::Planet>) -> Vec<f32> {
- let mut iter = planets.iter();
-
- let init = match iter.next() {
- Some(p) => (p.x, p.y, p.x, p.y),
- None => return vec![0.0, 0.0, 0.0, 0.0],
- };
- let (min_x, min_y, max_x, max_y) =
- planets
- .iter()
- .fold(init, |(min_x, min_y, max_x, max_y), p| {
- (
- min_x.min(p.x),
- min_y.min(p.y),
- max_x.max(p.x),
- max_y.max(p.y),
- )
- });
-
- let (width, height) = (max_x - min_x, max_y - min_y);
- let (dx, dy) = (
- (VIEWBOX_SCALE * width).max(6.0),
- (VIEWBOX_SCALE * height).max(6.0),
- );
-
- vec![min_x - dx / 2.0, min_y - dy / 2.0, width + dx, height + dy]
-}
-
-pub fn get_planets(planets: &Vec<types::Planet>, r: f32) -> Vec<f32> {
- planets.iter().fold(Vec::new(), |mut cum, p| {
- cum.push(p.x);
- cum.push(p.y);
- cum.push(r);
- cum
- })
-}