From 1b6a2835e57a7d399f43ecf493060e68042f9af8 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Wed, 12 Jun 2019 16:59:09 +0200 Subject: Clone the colored logging from old commit --- webhogg/wasm/Cargo.toml | 2 ++ webhogg/wasm/pkg/main.js | 12 ++++++++---- webhogg/wasm/pkg/worker-graphics.js | 1 - webhogg/wasm/pkg/worker.js | 9 +++++++++ webhogg/wasm/src/lib.rs | 12 ++++++++++-- webhogg/wasm/src/logger.rs | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 7 deletions(-) delete mode 100644 webhogg/wasm/pkg/worker-graphics.js create mode 100644 webhogg/wasm/pkg/worker.js create mode 100644 webhogg/wasm/src/logger.rs diff --git a/webhogg/wasm/Cargo.toml b/webhogg/wasm/Cargo.toml index 7978928..f4042c5 100644 --- a/webhogg/wasm/Cargo.toml +++ b/webhogg/wasm/Cargo.toml @@ -16,3 +16,5 @@ lto = true [dependencies] wasm-bindgen = "0.2" +log = "0.4" +fern = "0.5" diff --git a/webhogg/wasm/pkg/main.js b/webhogg/wasm/pkg/main.js index eec740d..ce96ee5 100644 --- a/webhogg/wasm/pkg/main.js +++ b/webhogg/wasm/pkg/main.js @@ -1,9 +1,13 @@ async function main() { let fetchingSource = fetch('bin/webhogg-wasm.wasm'); let fetchedSource = await fetchingSource; - let source = await fetchedSource.text(); - //alert(source) - let workerGraphics = new Worker('pkg/worker-graphics.js'); -} + source = await fetchedSource.arrayBuffer(); + let workers = []; + for (var type of ['graphics', 'logic']) { + let worker = new Worker('pkg/worker.js'); + worker.postMessage([type, source]); + workers.push(worker); + } +} main(); diff --git a/webhogg/wasm/pkg/worker-graphics.js b/webhogg/wasm/pkg/worker-graphics.js deleted file mode 100644 index 8360014..0000000 --- a/webhogg/wasm/pkg/worker-graphics.js +++ /dev/null @@ -1 +0,0 @@ -console.log('lelel'); diff --git a/webhogg/wasm/pkg/worker.js b/webhogg/wasm/pkg/worker.js new file mode 100644 index 0000000..bd11676 --- /dev/null +++ b/webhogg/wasm/pkg/worker.js @@ -0,0 +1,9 @@ +onmessage = async function (e) { + importScripts('../bin/webhogg-wasm.js'); + let ctx = await wasm_bindgen(e.data[1]); + + if (e.data[0] === 'graphics') + ctx.start_graphics(); + else if (e.data[0] === 'logic') + ctx.start_logic(); +} diff --git a/webhogg/wasm/src/lib.rs b/webhogg/wasm/src/lib.rs index cb334fb..bed779b 100644 --- a/webhogg/wasm/src/lib.rs +++ b/webhogg/wasm/src/lib.rs @@ -1,8 +1,16 @@ use wasm_bindgen::prelude::*; +use log::*; + +mod logger; #[wasm_bindgen] -pub fn enrty() { +pub fn start_graphics() { + logger::init_logger(); + info!("hello from wasm graphics"); } -fn main() { +#[wasm_bindgen] +pub fn start_logic() { + logger::init_logger(); + debug!("hello from wasm logic"); } diff --git a/webhogg/wasm/src/logger.rs b/webhogg/wasm/src/logger.rs new file mode 100644 index 0000000..96c4cbf --- /dev/null +++ b/webhogg/wasm/src/logger.rs @@ -0,0 +1,33 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace=console, js_name=log)] + fn __console_log_colored2(f: &str, c1: &str, c2: &str); +} + +fn log(rec: &log::Record) { + __console_log_colored2(&format!("{}", rec.args()), + &format!("color: {}", match rec.level() { + log::Level::Trace => "violet", + log::Level::Debug => "blue", + log::Level::Info => "green", + log::Level::Warn => "orange", + log::Level::Error => "red" + }), ""); +} + +pub fn init_logger() { + fern::Dispatch::new().format(|out, message, record|{ + out.finish(format_args!( + "%c{}%c {} > {}", + record.level(), + record.target(), + message + ) + ) + }) + .level(log::LevelFilter::Debug) + .chain(fern::Output::call(log)) + .apply().unwrap(); +} -- cgit v1.2.3 From c3fdf122bd874bd0aedf90eff0d57cc440fc6421 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Thu, 13 Jun 2019 00:38:21 +0200 Subject: Split code into graphics and logic loop --- webhogg/wasm/Cargo.toml | 5 +++++ webhogg/wasm/pkg/main.js | 22 +++++++++++++++++++--- webhogg/wasm/pkg/worker.js | 12 +++++++----- webhogg/wasm/src/context/graphics.rs | 11 +++++++++++ webhogg/wasm/src/context/logic.rs | 11 +++++++++++ webhogg/wasm/src/context/mod.rs | 24 ++++++++++++++++++++++++ webhogg/wasm/src/error.rs | 30 ++++++++++++++++++++++++++++++ webhogg/wasm/src/graphics.rs | 19 +++++++++++++++++++ webhogg/wasm/src/lib.rs | 19 ++++++------------- webhogg/wasm/src/logic.rs | 19 +++++++++++++++++++ 10 files changed, 151 insertions(+), 21 deletions(-) create mode 100644 webhogg/wasm/src/context/graphics.rs create mode 100644 webhogg/wasm/src/context/logic.rs create mode 100644 webhogg/wasm/src/context/mod.rs create mode 100644 webhogg/wasm/src/error.rs create mode 100644 webhogg/wasm/src/graphics.rs create mode 100644 webhogg/wasm/src/logic.rs diff --git a/webhogg/wasm/Cargo.toml b/webhogg/wasm/Cargo.toml index f4042c5..71b6a8e 100644 --- a/webhogg/wasm/Cargo.toml +++ b/webhogg/wasm/Cargo.toml @@ -18,3 +18,8 @@ lto = true wasm-bindgen = "0.2" log = "0.4" fern = "0.5" + +[dependencies.web-sys] +version = "0.3" +features = [ +] diff --git a/webhogg/wasm/pkg/main.js b/webhogg/wasm/pkg/main.js index ce96ee5..f16a775 100644 --- a/webhogg/wasm/pkg/main.js +++ b/webhogg/wasm/pkg/main.js @@ -1,12 +1,28 @@ +workers = []; + +function exit() { + for (var worker of workers) { + worker.terminate(); + } + console.clear(); +} + async function main() { let fetchingSource = fetch('bin/webhogg-wasm.wasm'); + + let canvasElement = document.getElementById('c'); + let offCanvas = canvasElement.transferControlToOffscreen(); + let fetchedSource = await fetchingSource; source = await fetchedSource.arrayBuffer(); - let workers = []; - for (var type of ['graphics', 'logic']) { + const modules = [ + ['graphics', source, [offCanvas], 100], + ['logic', source, [], 1000] + ]; + for (var module of modules) { let worker = new Worker('pkg/worker.js'); - worker.postMessage([type, source]); + worker.postMessage(module, module[2]); workers.push(worker); } } diff --git a/webhogg/wasm/pkg/worker.js b/webhogg/wasm/pkg/worker.js index bd11676..0b68374 100644 --- a/webhogg/wasm/pkg/worker.js +++ b/webhogg/wasm/pkg/worker.js @@ -1,9 +1,11 @@ onmessage = async function (e) { importScripts('../bin/webhogg-wasm.js'); - let ctx = await wasm_bindgen(e.data[1]); + let type = e.data[0]; + let source = e.data[1]; + let args = e.data[2]; + let dt = e.data[3]; + let ctx = await wasm_bindgen(source); - if (e.data[0] === 'graphics') - ctx.start_graphics(); - else if (e.data[0] === 'logic') - ctx.start_logic(); + ctx['start_' + type].apply(args); + setInterval(ctx['loop_' + type], dt); } diff --git a/webhogg/wasm/src/context/graphics.rs b/webhogg/wasm/src/context/graphics.rs new file mode 100644 index 0000000..57955d0 --- /dev/null +++ b/webhogg/wasm/src/context/graphics.rs @@ -0,0 +1,11 @@ +use crate::error::WasmError; + +pub struct GraphicsContext { +} + +impl GraphicsContext { + pub fn from_canvas() -> Result { + Ok(Self { + }) + } +} diff --git a/webhogg/wasm/src/context/logic.rs b/webhogg/wasm/src/context/logic.rs new file mode 100644 index 0000000..71dfea4 --- /dev/null +++ b/webhogg/wasm/src/context/logic.rs @@ -0,0 +1,11 @@ +use crate::error::WasmError; + +pub struct LogicContext { +} + +impl LogicContext { + pub fn new() -> Result { + Ok(Self { + }) + } +} diff --git a/webhogg/wasm/src/context/mod.rs b/webhogg/wasm/src/context/mod.rs new file mode 100644 index 0000000..3e8261b --- /dev/null +++ b/webhogg/wasm/src/context/mod.rs @@ -0,0 +1,24 @@ +pub mod graphics; +pub mod logic; + +use graphics::GraphicsContext; +use logic::LogicContext; + +static mut GTX: Option = None; +static mut LTX: Option = None; + +pub fn get_graphics() -> &'static mut GraphicsContext { + unsafe { GTX.as_mut().unwrap() } +} + +pub fn get_logic() -> &'static mut LogicContext { + unsafe { LTX.as_mut().unwrap() } +} + +pub fn set_graphics(gtx: GraphicsContext) { + unsafe { GTX = Some(gtx) } +} + +pub fn set_logic(ltx: LogicContext) { + unsafe { LTX = Some(ltx) } +} diff --git a/webhogg/wasm/src/error.rs b/webhogg/wasm/src/error.rs new file mode 100644 index 0000000..b544112 --- /dev/null +++ b/webhogg/wasm/src/error.rs @@ -0,0 +1,30 @@ +use std::error::Error; + +#[derive(Debug)] +pub enum WasmError { + TestError(String), +} + +impl std::fmt::Display for WasmError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + write!(f, "{}: {}", self.name(), self.description()) + } +} + +impl Error for WasmError { + fn description(&self) -> &str { + match self { + WasmError::TestError(msg) => msg, + } + } + + fn source(&self) -> Option<&'static dyn Error> { None } +} + +impl WasmError { + pub fn name(&self) -> &str { + match self { + WasmError::TestError(_) => "TestError", + } + } +} diff --git a/webhogg/wasm/src/graphics.rs b/webhogg/wasm/src/graphics.rs new file mode 100644 index 0000000..8169a3c --- /dev/null +++ b/webhogg/wasm/src/graphics.rs @@ -0,0 +1,19 @@ +use wasm_bindgen::prelude::*; +use log::*; +use crate::*; + +#[wasm_bindgen] +pub fn start_graphics() { + logger::init_logger(); + info!("graphics: wasm entry-point reached"); + + match context::graphics::GraphicsContext::from_canvas() { + Ok(ctx) => context::set_graphics(ctx), + Err(e) => error!("graphics {}", e) + } +} + +#[wasm_bindgen] +pub fn loop_graphics() { + debug!("graphics: loopin'"); +} diff --git a/webhogg/wasm/src/lib.rs b/webhogg/wasm/src/lib.rs index bed779b..7aa4e86 100644 --- a/webhogg/wasm/src/lib.rs +++ b/webhogg/wasm/src/lib.rs @@ -1,16 +1,9 @@ -use wasm_bindgen::prelude::*; -use log::*; - mod logger; +pub mod error; +pub mod context; -#[wasm_bindgen] -pub fn start_graphics() { - logger::init_logger(); - info!("hello from wasm graphics"); -} +pub mod logic; +pub mod graphics; -#[wasm_bindgen] -pub fn start_logic() { - logger::init_logger(); - debug!("hello from wasm logic"); -} +pub use logic::*; +pub use graphics::*; diff --git a/webhogg/wasm/src/logic.rs b/webhogg/wasm/src/logic.rs new file mode 100644 index 0000000..14272d9 --- /dev/null +++ b/webhogg/wasm/src/logic.rs @@ -0,0 +1,19 @@ +use wasm_bindgen::prelude::*; +use log::*; +use crate::*; + +#[wasm_bindgen] +pub fn start_logic() { + logger::init_logger(); + info!("logic: wasm entry-point reached"); + + match context::logic::LogicContext::new() { + Ok(ctx) => context::set_logic(ctx), + Err(e) => error!("logic {}", e) + } +} + +#[wasm_bindgen] +pub fn loop_logic() { + debug!("logic: loopin'"); +} -- cgit v1.2.3 From 5de862b4d175578ed67e177d482ac31bf811d486 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Thu, 13 Jun 2019 01:34:35 +0200 Subject: Create a WebGl2 context --- webhogg/wasm/Cargo.toml | 3 +++ webhogg/wasm/src/context/graphics.rs | 18 +++++++++++++++++- webhogg/wasm/src/error.rs | 6 +++--- webhogg/wasm/src/graphics.rs | 4 ++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/webhogg/wasm/Cargo.toml b/webhogg/wasm/Cargo.toml index 71b6a8e..2d69f41 100644 --- a/webhogg/wasm/Cargo.toml +++ b/webhogg/wasm/Cargo.toml @@ -18,8 +18,11 @@ lto = true wasm-bindgen = "0.2" log = "0.4" fern = "0.5" +js-sys = "0.3" [dependencies.web-sys] version = "0.3" features = [ + "OffscreenCanvas", + "WebGl2RenderingContext" ] diff --git a/webhogg/wasm/src/context/graphics.rs b/webhogg/wasm/src/context/graphics.rs index 57955d0..3476e5d 100644 --- a/webhogg/wasm/src/context/graphics.rs +++ b/webhogg/wasm/src/context/graphics.rs @@ -1,10 +1,26 @@ +use log::*; use crate::error::WasmError; +use wasm_bindgen::JsCast; +use web_sys::WebGl2RenderingContext as Gl; pub struct GraphicsContext { } impl GraphicsContext { - pub fn from_canvas() -> Result { + pub fn from_canvas(canvas: web_sys::OffscreenCanvas) -> Result { + let context = canvas.get_context("webgl2") + .map_err(|_| WasmError::WebGl2ContextCreation( + format!("context cration failed: getContext returned an exception")))? + .ok_or_else(|| WasmError::WebGl2ContextCreation( + format!("context cration failed: getContext returned nothing")))?; + let context = context + .dyn_into::() + .map_err(|_| WasmError::WebGl2ContextCreation( + format!("context object is not a context")))?; + + //context.clear(Gl::COLOR_BUFFER_BIT); + //context.clear_color(0.6, 0.0, 0.6, 1.0); + Ok(Self { }) } diff --git a/webhogg/wasm/src/error.rs b/webhogg/wasm/src/error.rs index b544112..1c6ec27 100644 --- a/webhogg/wasm/src/error.rs +++ b/webhogg/wasm/src/error.rs @@ -2,7 +2,7 @@ use std::error::Error; #[derive(Debug)] pub enum WasmError { - TestError(String), + WebGl2ContextCreation(String), } impl std::fmt::Display for WasmError { @@ -14,7 +14,7 @@ impl std::fmt::Display for WasmError { impl Error for WasmError { fn description(&self) -> &str { match self { - WasmError::TestError(msg) => msg, + WasmError::WebGl2ContextCreation(msg) => msg, } } @@ -24,7 +24,7 @@ impl Error for WasmError { impl WasmError { pub fn name(&self) -> &str { match self { - WasmError::TestError(_) => "TestError", + WasmError::WebGl2ContextCreation(_) => "WebGl2ContextCreationError", } } } diff --git a/webhogg/wasm/src/graphics.rs b/webhogg/wasm/src/graphics.rs index 8169a3c..a879c5e 100644 --- a/webhogg/wasm/src/graphics.rs +++ b/webhogg/wasm/src/graphics.rs @@ -3,11 +3,11 @@ use log::*; use crate::*; #[wasm_bindgen] -pub fn start_graphics() { +pub fn start_graphics(canvas: web_sys::OffscreenCanvas) { logger::init_logger(); info!("graphics: wasm entry-point reached"); - match context::graphics::GraphicsContext::from_canvas() { + match context::graphics::GraphicsContext::from_canvas(canvas) { Ok(ctx) => context::set_graphics(ctx), Err(e) => error!("graphics {}", e) } -- cgit v1.2.3 From 7884252333cc102a8144e4eafc36f9ef605b1be7 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Thu, 13 Jun 2019 03:21:53 +0200 Subject: Draw violet background --- webhogg/wasm/index.html | 4 +++- webhogg/wasm/pkg/main.js | 16 +++++++++++++--- webhogg/wasm/pkg/worker.js | 22 ++++++++++++++-------- webhogg/wasm/src/context/graphics.rs | 10 ++++++++-- webhogg/wasm/src/graphics.rs | 1 + 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/webhogg/wasm/index.html b/webhogg/wasm/index.html index eae1cc2..b6c8b9b 100644 --- a/webhogg/wasm/index.html +++ b/webhogg/wasm/index.html @@ -5,7 +5,9 @@ webhogg - your browser is incompetent + + your browser is incompetent + diff --git a/webhogg/wasm/pkg/main.js b/webhogg/wasm/pkg/main.js index f16a775..76afa1c 100644 --- a/webhogg/wasm/pkg/main.js +++ b/webhogg/wasm/pkg/main.js @@ -17,12 +17,22 @@ async function main() { source = await fetchedSource.arrayBuffer(); const modules = [ - ['graphics', source, [offCanvas], 100], - ['logic', source, [], 1000] + { type: 'graphics', + source: source, + canvas: offCanvas, + dt: 10000 }, + { type: 'logic', + source: source, + canvas: [], + dt: 10000 }, ]; for (var module of modules) { let worker = new Worker('pkg/worker.js'); - worker.postMessage(module, module[2]); + if (module.type === 'graphics') { + worker.postMessage(module, [module.canvas]); + } else { + worker.postMessage(module); + } workers.push(worker); } } diff --git a/webhogg/wasm/pkg/worker.js b/webhogg/wasm/pkg/worker.js index 0b68374..780ea6f 100644 --- a/webhogg/wasm/pkg/worker.js +++ b/webhogg/wasm/pkg/worker.js @@ -1,11 +1,17 @@ -onmessage = async function (e) { +let data = null; + +onmessage = function (e) { + data = e.data; + importScripts('../bin/webhogg-wasm.js'); - let type = e.data[0]; - let source = e.data[1]; - let args = e.data[2]; - let dt = e.data[3]; - let ctx = await wasm_bindgen(source); + wasm_bindgen(data.source).then(ctx => { + if (data.type === 'graphics') { + wasm_bindgen.start_graphics(data.canvas); + setInterval(wasm_bindgen.loop_graphics, data.dt); + } else if (data.type === 'logic') { + wasm_bindgen.start_logic(); + setInterval(wasm_bindgen.loop_logic, data.dt); + } - ctx['start_' + type].apply(args); - setInterval(ctx['loop_' + type], dt); + }); } diff --git a/webhogg/wasm/src/context/graphics.rs b/webhogg/wasm/src/context/graphics.rs index 3476e5d..853e1e1 100644 --- a/webhogg/wasm/src/context/graphics.rs +++ b/webhogg/wasm/src/context/graphics.rs @@ -8,6 +8,12 @@ pub struct GraphicsContext { impl GraphicsContext { pub fn from_canvas(canvas: web_sys::OffscreenCanvas) -> Result { + /*debug!("canvas object usw.: {:?}", canvas); + let canvas: web_sys::OffscreenCanvas = js_sys::Reflect::get(&canvas, + &wasm_bindgen::JsValue::from_str("canvas")) + .map_err(|_| WasmError::WebGl2ContextCreation( + format!("canvas object is not defined")))? + .into();*/ let context = canvas.get_context("webgl2") .map_err(|_| WasmError::WebGl2ContextCreation( format!("context cration failed: getContext returned an exception")))? @@ -18,8 +24,8 @@ impl GraphicsContext { .map_err(|_| WasmError::WebGl2ContextCreation( format!("context object is not a context")))?; - //context.clear(Gl::COLOR_BUFFER_BIT); - //context.clear_color(0.6, 0.0, 0.6, 1.0); + context.clear_color(0.6, 0.0, 0.6, 1.0); + context.clear(Gl::COLOR_BUFFER_BIT); Ok(Self { }) diff --git a/webhogg/wasm/src/graphics.rs b/webhogg/wasm/src/graphics.rs index a879c5e..690b4cd 100644 --- a/webhogg/wasm/src/graphics.rs +++ b/webhogg/wasm/src/graphics.rs @@ -6,6 +6,7 @@ use crate::*; pub fn start_graphics(canvas: web_sys::OffscreenCanvas) { logger::init_logger(); info!("graphics: wasm entry-point reached"); + //debug!("js value is?: undefined: {}", canvas.is_undefined()); match context::graphics::GraphicsContext::from_canvas(canvas) { Ok(ctx) => context::set_graphics(ctx), -- cgit v1.2.3 From 03cedca74429c326fcca176576702873e32a8455 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Thu, 13 Jun 2019 17:21:44 +0200 Subject: Add rendering loop --- webhogg/wasm/index.html | 4 ++-- webhogg/wasm/pkg/main.js | 2 +- webhogg/wasm/src/context/graphics.rs | 29 ++++++++++++++++++++--------- webhogg/wasm/src/graphics.rs | 4 +++- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/webhogg/wasm/index.html b/webhogg/wasm/index.html index b6c8b9b..315d9cb 100644 --- a/webhogg/wasm/index.html +++ b/webhogg/wasm/index.html @@ -4,8 +4,8 @@ webhogg - - + + your browser is incompetent diff --git a/webhogg/wasm/pkg/main.js b/webhogg/wasm/pkg/main.js index 76afa1c..90b3956 100644 --- a/webhogg/wasm/pkg/main.js +++ b/webhogg/wasm/pkg/main.js @@ -20,7 +20,7 @@ async function main() { { type: 'graphics', source: source, canvas: offCanvas, - dt: 10000 }, + dt: 16 }, { type: 'logic', source: source, canvas: [], diff --git a/webhogg/wasm/src/context/graphics.rs b/webhogg/wasm/src/context/graphics.rs index 853e1e1..b94441d 100644 --- a/webhogg/wasm/src/context/graphics.rs +++ b/webhogg/wasm/src/context/graphics.rs @@ -4,16 +4,12 @@ use wasm_bindgen::JsCast; use web_sys::WebGl2RenderingContext as Gl; pub struct GraphicsContext { + gl: Gl, + frame_nr: u64, } impl GraphicsContext { pub fn from_canvas(canvas: web_sys::OffscreenCanvas) -> Result { - /*debug!("canvas object usw.: {:?}", canvas); - let canvas: web_sys::OffscreenCanvas = js_sys::Reflect::get(&canvas, - &wasm_bindgen::JsValue::from_str("canvas")) - .map_err(|_| WasmError::WebGl2ContextCreation( - format!("canvas object is not defined")))? - .into();*/ let context = canvas.get_context("webgl2") .map_err(|_| WasmError::WebGl2ContextCreation( format!("context cration failed: getContext returned an exception")))? @@ -23,11 +19,26 @@ impl GraphicsContext { .dyn_into::() .map_err(|_| WasmError::WebGl2ContextCreation( format!("context object is not a context")))?; - - context.clear_color(0.6, 0.0, 0.6, 1.0); - context.clear(Gl::COLOR_BUFFER_BIT); Ok(Self { + gl: context, + frame_nr: 0, }) } + + pub fn update(&mut self) -> Result<(), WasmError> { + let light = 0.5; + + let a = (self.frame_nr as f32) / 60.0; + let a = f32::abs(f32::sin(a)); + let b = f32::abs(f32::cos(a)); + let (a, b) = (a * light, b * light); + + self.gl.clear_color(a, light - a, b, 1.0); + self.gl.clear(Gl::COLOR_BUFFER_BIT); + + self.frame_nr += 1; + + Ok(()) + } } diff --git a/webhogg/wasm/src/graphics.rs b/webhogg/wasm/src/graphics.rs index 690b4cd..c4902ae 100644 --- a/webhogg/wasm/src/graphics.rs +++ b/webhogg/wasm/src/graphics.rs @@ -16,5 +16,7 @@ pub fn start_graphics(canvas: web_sys::OffscreenCanvas) { #[wasm_bindgen] pub fn loop_graphics() { - debug!("graphics: loopin'"); + context::get_graphics().update() + .map_err(|e| error!("gaphics loop {}", e)) + .unwrap(); } -- cgit v1.2.3 From b75597c140e9b4758a1ad803044dda96b403e1a5 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Fri, 14 Jun 2019 00:13:15 +0200 Subject: Wrap WebGl2 --- webhogg/wasm/src/context/graphics.rs | 19 +++++++++++-------- webhogg/wasm/src/context/mod.rs | 1 + webhogg/wasm/src/context/webgl.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 webhogg/wasm/src/context/webgl.rs diff --git a/webhogg/wasm/src/context/graphics.rs b/webhogg/wasm/src/context/graphics.rs index b94441d..fa37e39 100644 --- a/webhogg/wasm/src/context/graphics.rs +++ b/webhogg/wasm/src/context/graphics.rs @@ -1,10 +1,12 @@ use log::*; use crate::error::WasmError; use wasm_bindgen::JsCast; -use web_sys::WebGl2RenderingContext as Gl; +use web_sys::WebGl2RenderingContext as GlContext; + +use super::webgl::{Color4, WebGl2}; pub struct GraphicsContext { - gl: Gl, + gl: WebGl2, frame_nr: u64, } @@ -16,26 +18,27 @@ impl GraphicsContext { .ok_or_else(|| WasmError::WebGl2ContextCreation( format!("context cration failed: getContext returned nothing")))?; let context = context - .dyn_into::() + .dyn_into::() .map_err(|_| WasmError::WebGl2ContextCreation( format!("context object is not a context")))?; + + let gl = WebGl2::from_context(context); Ok(Self { - gl: context, - frame_nr: 0, + gl, frame_nr: 0, }) } pub fn update(&mut self) -> Result<(), WasmError> { let light = 0.5; + let speed = 60.0; - let a = (self.frame_nr as f32) / 60.0; + let a = (self.frame_nr as f32) / speed; let a = f32::abs(f32::sin(a)); let b = f32::abs(f32::cos(a)); let (a, b) = (a * light, b * light); - self.gl.clear_color(a, light - a, b, 1.0); - self.gl.clear(Gl::COLOR_BUFFER_BIT); + self.gl.clear(Color4::new(a, light - a, b, 1.0)); self.frame_nr += 1; diff --git a/webhogg/wasm/src/context/mod.rs b/webhogg/wasm/src/context/mod.rs index 3e8261b..a581047 100644 --- a/webhogg/wasm/src/context/mod.rs +++ b/webhogg/wasm/src/context/mod.rs @@ -1,3 +1,4 @@ +mod webgl; pub mod graphics; pub mod logic; diff --git a/webhogg/wasm/src/context/webgl.rs b/webhogg/wasm/src/context/webgl.rs new file mode 100644 index 0000000..abecc6e --- /dev/null +++ b/webhogg/wasm/src/context/webgl.rs @@ -0,0 +1,26 @@ +use web_sys::WebGl2RenderingContext as GlContext; + +pub struct Color4(f32, f32, f32, f32); + +impl Color4 { + pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color4 { + Color4(r, g, b, a) + } +} + +pub struct WebGl2 { + gl: GlContext, +} + +impl WebGl2 { + pub fn from_context(context: GlContext) -> Self { + WebGl2 { + gl: context, + } + } + + pub fn clear(&self, color: Color4) { + self.gl.clear_color(color.0, color.1, color.2, color.3); + self.gl.clear(GlContext::COLOR_BUFFER_BIT); + } +} -- cgit v1.2.3 From 4fd207e78452a9e282ef65fc9c3eaf8b19115956 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Fri, 14 Jun 2019 00:18:35 +0200 Subject: Fill all screen space with the canvas --- webhogg/wasm/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webhogg/wasm/index.html b/webhogg/wasm/index.html index 315d9cb..350c58d 100644 --- a/webhogg/wasm/index.html +++ b/webhogg/wasm/index.html @@ -4,8 +4,8 @@ webhogg - - + + your browser is incompetent -- cgit v1.2.3 From 438825a7ce98a0cd455ff0adebd6d3cf8d3209be Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Fri, 14 Jun 2019 17:20:01 +0200 Subject: Draw a rectangle --- webhogg/wasm/Cargo.toml | 6 +- webhogg/wasm/src/context/graphics.rs | 40 ++++++++++++- webhogg/wasm/src/context/main.fs | 9 +++ webhogg/wasm/src/context/main.vs | 9 +++ webhogg/wasm/src/context/mod.rs | 1 + webhogg/wasm/src/context/shader.rs | 34 +++++++++++ webhogg/wasm/src/context/webgl.rs | 112 ++++++++++++++++++++++++++++++++++- webhogg/wasm/src/error.rs | 6 ++ webhogg/wasm/src/graphics.rs | 5 +- 9 files changed, 215 insertions(+), 7 deletions(-) create mode 100644 webhogg/wasm/src/context/main.fs create mode 100644 webhogg/wasm/src/context/main.vs create mode 100644 webhogg/wasm/src/context/shader.rs diff --git a/webhogg/wasm/Cargo.toml b/webhogg/wasm/Cargo.toml index 2d69f41..8f44389 100644 --- a/webhogg/wasm/Cargo.toml +++ b/webhogg/wasm/Cargo.toml @@ -24,5 +24,9 @@ js-sys = "0.3" version = "0.3" features = [ "OffscreenCanvas", - "WebGl2RenderingContext" + "WebGl2RenderingContext", + "WebGlShader", + "WebGlProgram", + "WebGlBuffer", + "WebGlVertexArrayObject" ] diff --git a/webhogg/wasm/src/context/graphics.rs b/webhogg/wasm/src/context/graphics.rs index fa37e39..6af35a2 100644 --- a/webhogg/wasm/src/context/graphics.rs +++ b/webhogg/wasm/src/context/graphics.rs @@ -1,13 +1,18 @@ -use log::*; use crate::error::WasmError; use wasm_bindgen::JsCast; use web_sys::WebGl2RenderingContext as GlContext; -use super::webgl::{Color4, WebGl2}; +use super::webgl; +use super::webgl::{Color4, ShaderType, WebGl2}; +use super::shader::{MAIN_VERTEX_SHADER, MAIN_FRAGMENT_SHADER}; +use super::shader::ShaderProgram; pub struct GraphicsContext { gl: WebGl2, frame_nr: u64, + shader: ShaderProgram, + vao: webgl::WebGlVertexArrayObject, + buffer: webgl::WebGlBuffer, } impl GraphicsContext { @@ -23,9 +28,33 @@ impl GraphicsContext { format!("context object is not a context")))?; let gl = WebGl2::from_context(context); + let shader = ShaderProgram::from_sources(&gl, &[ + (ShaderType::Vertex, MAIN_VERTEX_SHADER.to_string()), + (ShaderType::Fragment, MAIN_FRAGMENT_SHADER.to_string()), + ])?; + + let vao = gl.create_vertex_array() + .map_err(|_| WasmError::WebGlBuffer( + format!("glGenVertexArrays failed")))?; + gl.bind_vertex_array(&vao); + + let buffer = gl.create_buffer() + .map_err(|_| WasmError::WebGlBuffer( + format!("glCreateBuffer failed")))?; + gl.bind_array_buffer(&buffer); + gl.array_buffer_data_f32(&[ + 0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + 0.0, 1.0, + 1.0, 0.0, + ]); + gl.enable_vertex_attrib_array(0); Ok(Self { gl, frame_nr: 0, + shader, vao, buffer }) } @@ -38,7 +67,12 @@ impl GraphicsContext { let b = f32::abs(f32::cos(a)); let (a, b) = (a * light, b * light); - self.gl.clear(Color4::new(a, light - a, b, 1.0)); + self.gl.set_viewport(); + self.gl.clear(&Color4::new(a, light - a, b, 1.0)); + + self.shader.run(&self.gl); + self.gl.vertex_attrib_f32_pointer(0, 2); + self.gl.draw_triangle_arrays(6); self.frame_nr += 1; diff --git a/webhogg/wasm/src/context/main.fs b/webhogg/wasm/src/context/main.fs new file mode 100644 index 0000000..971d2db --- /dev/null +++ b/webhogg/wasm/src/context/main.fs @@ -0,0 +1,9 @@ +#version 300 es + +precision highp float; + +out vec4 color; + +void main() { + color = vec4(0.0, 1.0, 1.0, 1.0); +} diff --git a/webhogg/wasm/src/context/main.vs b/webhogg/wasm/src/context/main.vs new file mode 100644 index 0000000..18df0a0 --- /dev/null +++ b/webhogg/wasm/src/context/main.vs @@ -0,0 +1,9 @@ +#version 300 es + +precision highp float; + +layout(location=0) in vec2 position; + +void main() { + gl_Position = vec4(position, 0.0, 0.0); +} diff --git a/webhogg/wasm/src/context/mod.rs b/webhogg/wasm/src/context/mod.rs index a581047..09902ce 100644 --- a/webhogg/wasm/src/context/mod.rs +++ b/webhogg/wasm/src/context/mod.rs @@ -1,3 +1,4 @@ +mod shader; mod webgl; pub mod graphics; pub mod logic; diff --git a/webhogg/wasm/src/context/shader.rs b/webhogg/wasm/src/context/shader.rs new file mode 100644 index 0000000..9ccb9fc --- /dev/null +++ b/webhogg/wasm/src/context/shader.rs @@ -0,0 +1,34 @@ +use crate::error::WasmError; +use super::webgl; +use super::webgl::{WebGl2, ShaderType}; + +pub const MAIN_VERTEX_SHADER: &str = include_str!("main.vs"); +pub const MAIN_FRAGMENT_SHADER: &str = include_str!("main.fs"); + +pub struct ShaderProgram { + program: webgl::WebGlProgram, +} + +impl ShaderProgram { + pub fn from_sources(gl: &WebGl2, sources: &[(ShaderType, String)]) -> Result { + let program = gl.create_program() + .map_err(|_| WasmError::Shader(format!("glCreateProgram failed ({})", gl.get_error())))?; + for (shader_type, source) in sources { + let shader = gl.create_shader(shader_type) + .map_err(|_| WasmError::Shader(format!("glCreateShader failed ({})", gl.get_error())))?; + gl.shader_source(&shader, source); + gl.compile_shader(&shader) + .map_err(|e| WasmError::Shader(format!("compile error in {} shader: {}", shader_type, e)))?; + gl.attach_shader(&program, &shader) + } + gl.link_program(&program) + .map_err(|e| WasmError::Shader(format!("linker error in program: {}", e)))?; + Ok(Self { + program + }) + } + + pub fn run(&self, gl: &WebGl2) { + gl.use_program(&self.program) + } +} diff --git a/webhogg/wasm/src/context/webgl.rs b/webhogg/wasm/src/context/webgl.rs index abecc6e..8883835 100644 --- a/webhogg/wasm/src/context/webgl.rs +++ b/webhogg/wasm/src/context/webgl.rs @@ -1,13 +1,50 @@ -use web_sys::WebGl2RenderingContext as GlContext; +pub use web_sys::{ + WebGl2RenderingContext as GlContext, + WebGlProgram, WebGlShader, + WebGlBuffer, WebGlVertexArrayObject, +}; +use wasm_bindgen::prelude::*; +use std::fmt::Display; pub struct Color4(f32, f32, f32, f32); +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace=Float32Array, js_name=of, variadic)] + fn _create_f32_buffer(args: &[f32]) -> js_sys::Float32Array; +} + +#[derive(Debug)] +pub enum ShaderType { + Vertex, + Fragment, +} + +impl Display for ShaderType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl ShaderType { + pub fn to_id(&self) -> u32 { + match self { + ShaderType::Vertex => GlContext::VERTEX_SHADER, + ShaderType::Fragment => GlContext::FRAGMENT_SHADER, + } + } +} + impl Color4 { pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color4 { Color4(r, g, b, a) } } +pub fn create_f32_buffer(buffer: &[f32]) -> js_sys::Float32Array { + _create_f32_buffer(buffer) +} + pub struct WebGl2 { gl: GlContext, } @@ -19,8 +56,79 @@ impl WebGl2 { } } - pub fn clear(&self, color: Color4) { + pub fn create_program(&self) -> Result { + self.gl.create_program().ok_or(()) + } + + pub fn create_shader(&self, shader_type: &ShaderType) -> Result { + self.gl.create_shader(shader_type.to_id()).ok_or(()) + } + + pub fn get_error(&self) -> u32 { self.gl.get_error() } + pub fn shader_source(&self, id: &WebGlShader, source: &str) { self.gl.shader_source(id, source) } + pub fn compile_shader(&self, id: &WebGlShader) -> Result<(), String> { + self.gl.compile_shader(id); + if self.gl.get_shader_parameter(id, GlContext::COMPILE_STATUS) == JsValue::FALSE { + Err(self.gl.get_shader_info_log(id) + .unwrap_or("/could not retrieve program information/".to_string())) + } else { Ok(()) } + } + pub fn link_program(&self, id: &WebGlProgram) -> Result<(), String> { + self.gl.link_program(id); + if self.gl.get_program_parameter(id, GlContext::LINK_STATUS) == JsValue::FALSE { + Err(self.gl.get_program_info_log(id) + .unwrap_or("/could not retrieve program information/".to_string())) + } else { Ok(()) } + } + pub fn attach_shader(&self, program: &WebGlProgram, shader: &WebGlShader) { + self.gl.attach_shader(program, shader) + } + + pub fn clear(&self, color: &Color4) { self.gl.clear_color(color.0, color.1, color.2, color.3); self.gl.clear(GlContext::COLOR_BUFFER_BIT); } + + pub fn set_viewport(&self) { + self.gl.viewport(0, 0, self.gl.drawing_buffer_width(), self.gl.drawing_buffer_height()); + } + + pub fn create_buffer(&self) -> Result { + self.gl.create_buffer().ok_or(()) + } + + pub fn bind_array_buffer(&self, buffer: &WebGlBuffer) { + self.gl.bind_buffer(GlContext::ARRAY_BUFFER, Some(buffer)) + } + pub fn unbind_array_buffer(&self) { self.gl.bind_buffer(GlContext::ARRAY_BUFFER, None) } + + pub fn array_buffer_data_f32(&self, data: &[f32]) { + self.gl.buffer_data_with_opt_array_buffer( + GlContext::ARRAY_BUFFER, + Some(&create_f32_buffer(data).buffer()), + GlContext::STATIC_DRAW) + } + + pub fn create_vertex_array(&self) -> Result { + self.gl.create_vertex_array().ok_or(()) + } + pub fn bind_vertex_array(&self, array: &WebGlVertexArrayObject) { + self.gl.bind_vertex_array(Some(array)) + } + pub fn unbind_vertex_array(&self) { self.gl.bind_vertex_array(None) } + pub fn vertex_attrib_f32_pointer(&self, location: u32, dim: i32) { + self.gl.vertex_attrib_pointer_with_i32(location, dim, GlContext::FLOAT, false, 0, 0) + } + + pub fn draw_triangle_arrays(&self, count: i32) { + self.gl.draw_arrays(GlContext::TRIANGLES, 0, count) + } + + pub fn enable_vertex_attrib_array(&self, location: u32) { + self.gl.enable_vertex_attrib_array(location) + } + + pub fn use_program(&self, program: &WebGlProgram) { + self.gl.use_program(Some(program)) + } } diff --git a/webhogg/wasm/src/error.rs b/webhogg/wasm/src/error.rs index 1c6ec27..fbb6bf8 100644 --- a/webhogg/wasm/src/error.rs +++ b/webhogg/wasm/src/error.rs @@ -3,6 +3,8 @@ use std::error::Error; #[derive(Debug)] pub enum WasmError { WebGl2ContextCreation(String), + Shader(String), + WebGlBuffer(String), } impl std::fmt::Display for WasmError { @@ -15,6 +17,8 @@ impl Error for WasmError { fn description(&self) -> &str { match self { WasmError::WebGl2ContextCreation(msg) => msg, + WasmError::Shader(msg) => msg, + WasmError::WebGlBuffer(msg) => msg, } } @@ -25,6 +29,8 @@ impl WasmError { pub fn name(&self) -> &str { match self { WasmError::WebGl2ContextCreation(_) => "WebGl2ContextCreationError", + WasmError::Shader(_) => "ShaderError", + WasmError::WebGlBuffer(_) => "WebGlBufferError", } } } diff --git a/webhogg/wasm/src/graphics.rs b/webhogg/wasm/src/graphics.rs index c4902ae..219c652 100644 --- a/webhogg/wasm/src/graphics.rs +++ b/webhogg/wasm/src/graphics.rs @@ -10,7 +10,10 @@ pub fn start_graphics(canvas: web_sys::OffscreenCanvas) { match context::graphics::GraphicsContext::from_canvas(canvas) { Ok(ctx) => context::set_graphics(ctx), - Err(e) => error!("graphics {}", e) + Err(e) => { + error!("graphics {}", e); + panic!() + } } } -- cgit v1.2.3 From a4532a3f034850c9fe8e26cc210bda618136dcbf Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Fri, 14 Jun 2019 17:28:36 +0200 Subject: Adapt canvas rendering resolution to screen size --- webhogg/wasm/index.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/webhogg/wasm/index.html b/webhogg/wasm/index.html index 350c58d..a992390 100644 --- a/webhogg/wasm/index.html +++ b/webhogg/wasm/index.html @@ -8,6 +8,11 @@ your browser is incompetent + -- cgit v1.2.3 From 6fc34ce9e0485a093487baf50738fc1ffb70ce82 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 14 Jun 2019 17:42:02 +0200 Subject: Fix canvas width --- webhogg/wasm/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webhogg/wasm/index.html b/webhogg/wasm/index.html index 315d9cb..9624ad8 100644 --- a/webhogg/wasm/index.html +++ b/webhogg/wasm/index.html @@ -4,8 +4,8 @@ webhogg - - + + your browser is incompetent -- cgit v1.2.3 From 4392c7fca245b8702932fbc5e0ed011bc0c6f00c Mon Sep 17 00:00:00 2001 From: konsumlamm Date: Fri, 21 Jun 2019 20:56:21 +0200 Subject: refactor maths.rs to math.rs --- webhogg/game_server/src/math.rs | 369 ++++++++++++++++++++++++++++++++++++++ webhogg/game_server/src/maths.rs | 370 --------------------------------------- 2 files changed, 369 insertions(+), 370 deletions(-) create mode 100644 webhogg/game_server/src/math.rs delete mode 100644 webhogg/game_server/src/maths.rs diff --git a/webhogg/game_server/src/math.rs b/webhogg/game_server/src/math.rs new file mode 100644 index 0000000..6d9f1e1 --- /dev/null +++ b/webhogg/game_server/src/math.rs @@ -0,0 +1,369 @@ +#[derive(Clone, Copy, Debug)] +pub struct Vec2 { + pub x: f32, + pub y: f32, +} + +impl std::ops::Add for Vec2 { + type Output = Self; + fn add(self, other: Self) -> Self { + Self { + x: self.x + other.x, + y: self.y + other.y + } + } +} + +impl std::ops::AddAssign for Vec2 { + fn add_assign(&mut self, other: Vec2) { + self.x += other.x; + self.y += other.y; + } +} + +impl std::ops::Sub for Vec2 { + type Output = Self; + fn sub(self, other: Self) -> Self { + Self { + x: self.x - other.x, + y: self.y - other.y + } + } +} + +impl std::ops::SubAssign for Vec2 { + fn sub_assign(&mut self, other: Vec2) { + self.x -= other.x; + self.y -= other.y; + } +} + +impl std::ops::Neg for Vec2 { + type Output = Self; + fn neg(self) -> Self { + Self { + x: -self.x, + y: -self.y + } + } +} + +impl std::ops::Mul for Vec2 { + type Output = Self; + fn mul(self, scale: f32) -> Self { + Self { + x: self.x * scale, + y: self.y * scale + } + } +} + +impl std::ops::Div for Vec2 { + type Output = Self; + fn div(self, scale: f32) -> Self { + Self { + x: self.x / scale, + y: self.y / scale + } + } +} + +impl std::ops::Div for Vec2 { + type Output = Self; + fn div(self, scale: Vec2) -> Self { + Self { + x: self.x / scale.x, + y: self.y / scale.y + } + } +} + + +impl std::cmp::PartialOrd for Vec2 { + fn partial_cmp(&self, other: &Self) -> Option { + if self.x <= other.x && self.y <= other.y { + Some(std::cmp::Ordering::Less) + } else if self.x > other.x && self.y > other.y { + Some(std::cmp::Ordering::Greater) + } else { + None + } + } +} + +impl std::cmp::PartialEq for Vec2 { + fn eq(&self, other: &Self) -> bool { + f32::abs(self.x - other.x) < 1e-8 + && f32::abs(self.y - other.y) < 1e-8 + } +} + +impl std::cmp::Eq for Vec2 {} + +impl Vec2 { + pub fn norm(&self) -> f32 { + f32::hypot(self.x, self.y) + } + + pub fn norm2(&self) -> f32 { + self.dot(self) + } + + pub fn dot(&self, other: &Vec2) -> f32 { + self.x * other.x + self.y * other.y + } + + pub fn normalized(&self) -> Vec2 { + let len = self.norm(); + Vec2 { + x: self.x / len, + y: self.y / len, + } + } +} + +#[derive(Clone, Copy, Debug)] +pub struct AABox { + pub pos: Vec2, + /// the size may not be smaller than zero + pub size: Vec2, +} + +impl std::ops::Add for AABox { + type Output = Self; + fn add(self, other: Vec2) -> Self { + Self { + pos: self.pos + other, + size: self.size, + } + } +} + +impl std::ops::AddAssign for AABox { + fn add_assign(&mut self, other: Vec2) { + self.pos += other + } +} + +impl std::ops::Sub for AABox { + type Output = Self; + fn sub(self, other: Vec2) -> Self { + Self { + pos: self.pos - other, + size: self.size + } + } +} + +impl std::ops::SubAssign for AABox { + fn sub_assign(&mut self, other: Vec2) { + self.pos -= other + } +} + +impl std::cmp::PartialEq for AABox { + fn eq(&self, other: &Self) -> bool { + self.pos == other.pos + && self.size == other.size + } +} + +impl std::cmp::Eq for AABox {} + +#[derive(Clone, Copy, Debug)] +pub struct RBox { + /// origin + pub pos: Vec2, + /// Vector1 + pub v1: Vec2, + /// Vector2 + pub v2: Vec2, +} + +impl RBox { + pub fn new(pos: Vec2, orientation: Vec2, width: f32) -> Self { + let scale = width / orientation.norm(); + let orth = Vec2 {x: orientation.x / scale, y: -orientation.y / scale}; + Self { + pos: pos, + v1: orientation, + v2: orth, + } + } +} + +impl std::ops::Add for RBox { + type Output = Self; + fn add(self, other: Vec2) -> Self { + Self { + pos: self.pos + other, + v1: self.v1, + v2: self.v2, + } + } +} + +impl std::ops::AddAssign for RBox { + fn add_assign(&mut self, other: Vec2) { + self.pos += other + } +} + +impl std::ops::Sub for RBox { + type Output = Self; + fn sub(self, other: Vec2) -> Self { + Self { + pos: self.pos - other, + v1: self.v1, + v2: self.v2, + } + } +} + +impl std::ops::SubAssign for RBox { + fn sub_assign(&mut self, other: Vec2) { + self.pos -= other + } +} + +impl std::cmp::PartialEq for RBox { + fn eq(&self, other: &Self) -> bool { + self.pos == other.pos + && self.v1 == other.v1 + && self.v2 == other.v2 + } +} + +impl std::cmp::Eq for RBox {} + +#[cfg(test)] +mod tests { + // Note this useful idiom: importing names from outer (for mod tests) scope. + use super::*; + + #[test] + fn test_less_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -3.0, y: 2.5}; + + assert!(b < a); + } + + #[test] + fn test_less_vec2_fail() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: 3.0, y: 2.5}; + + assert!(!(a < b)); + } + + #[test] + fn test_greater_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -3.0, y: 2.5}; + + assert!(a > b); + } + + #[test] + fn test_greater_vec2_fail() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: 3.0, y: 2.5}; + + assert!(!(a > b)); + } + + #[test] + fn test_add_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -3.0, y: 2.5}; + let c = Vec2{x: -2.0, y: 10.0}; + + assert_eq!(a + b, c); + } + + #[test] + fn test_neg_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -1.0, y: -7.5}; + + assert_eq!(-a, b); + } + + #[test] + fn test_sub_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -3.0, y: 2.5}; + let c = Vec2{x: 4.0, y: 5.0}; + + assert_eq!(a - b, c); + } + + #[test] + fn test_norm_vec2() { + let a = Vec2{x: 2.0, y: 2.0}; + + assert!(f32::abs(a.norm() - 2.0) < 1e8); + } + + #[test] + fn test_norm2_vec2() { + let a = Vec2{x: 1.0, y: 2.0}; + + assert!(f32::abs(a.norm2() - 5.0) < 1e8); + } + + #[test] + fn test_normalized_vec2() { + let a = Vec2{x: 2.0, y: -2.0}; + let b = Vec2{x: std::f32::consts::FRAC_1_SQRT_2, y: -std::f32::consts::FRAC_1_SQRT_2}; + + assert_eq!(a.normalized(), b); + } + + #[test] + fn test_add_aabox_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -3.0, y: 2.5}; + let mut aa_box = AABox{pos: a, size: b}; + let bb_box = AABox{pos: a + b,size: b}; + aa_box += b; + + assert_eq!(aa_box, bb_box); + } + + #[test] + fn test_sub_aabox_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -3.0, y: 2.5}; + let mut aa_box = AABox{pos: a, size: b}; + let bb_box = AABox{pos: a - b,size: b}; + aa_box -= b; + + assert_eq!(aa_box, bb_box); + } + + #[test] + fn test_add_rbox_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -3.0, y: 2.5}; + let c = Vec2{x: -3.0, y: 2.5}; + let mut aa_box = RBox{pos: a, v1: b, v2: c}; + let bb_box = RBox{pos: a + b, v1: b, v2: c}; + aa_box += b; + + assert_eq!(aa_box, bb_box); + } + + #[test] + fn test_sub_rbox_vec2() { + let a = Vec2{x: 1.0, y: 7.5}; + let b = Vec2{x: -3.0, y: 2.5}; + let c = Vec2{x: -3.0, y: 2.5}; + let mut aa_box = RBox{pos: a, v1: b, v2: c}; + let bb_box = RBox{pos: a - b, v1: b, v2: c}; + aa_box -= b; + + assert_eq!(aa_box, bb_box); + } +} diff --git a/webhogg/game_server/src/maths.rs b/webhogg/game_server/src/maths.rs deleted file mode 100644 index b9303af..0000000 --- a/webhogg/game_server/src/maths.rs +++ /dev/null @@ -1,370 +0,0 @@ -#[derive(Clone, Copy, Debug)] -pub struct Vec2 { - pub x: f32, - pub y: f32, -} - -impl std::ops::Add for Vec2 { - type Output = Self; - fn add(self, other: Self) -> Self { - Self { - x: self.x + other.x, - y: self.y + other.y - } - } -} - -impl std::ops::AddAssign for Vec2 { - fn add_assign(&mut self, other: Vec2) { - self.x += other.x; - self.y += other.y; - } -} - -impl std::ops::Sub for Vec2 { - type Output = Self; - fn sub(self, other: Self) -> Self { - Self { - x: self.x - other.x, - y: self.y - other.y - } - } -} - -impl std::ops::SubAssign for Vec2 { - fn sub_assign(&mut self, other: Vec2) { - self.x -= other.x; - self.y -= other.y; - } -} - -impl std::ops::Neg for Vec2 { - type Output = Self; - fn neg(self) -> Self { - Self { - x: -self.x, - y: -self.y - } - } -} - -impl std::ops::Mul for Vec2 { - type Output = Self; - fn mul(self, scale: f32) -> Self { - Self { - x: self.x * scale, - y: self.y * scale - } - } -} - -impl std::ops::Div for Vec2 { - type Output = Self; - fn div(self, scale: f32) -> Self { - Self { - x: self.x / scale, - y: self.y / scale - } - } -} - -impl std::ops::Div for Vec2 { - type Output = Self; - fn div(self, scale: Vec2) -> Self { - Self { - x: self.x / scale.x, - y: self.y / scale.y - } - } -} - - -impl std::cmp::PartialOrd for Vec2 { - fn partial_cmp(&self, other: &Self) -> Option { - if self.x <= other.x && self.y <= other.y { - Some(std::cmp::Ordering::Less) - } else if self.x > other.x && self.y > other.y { - Some(std::cmp::Ordering::Greater) - } else { - None - } - } -} - -impl std::cmp::PartialEq for Vec2 { - fn eq(&self, other: &Self) -> bool { - f32::abs(self.x - other.x) < 1e-8 - && f32::abs(self.y - other.y) < 1e-8 - } -} - -impl std::cmp::Eq for Vec2 {} - -impl Vec2 { - pub fn distance(&self) -> f32 { - f32::sqrt(self.distance2()) - } - - pub fn distance2(&self) -> f32 { - self.scalar(self) - } - - pub fn scalar(&self, other: &Vec2) -> f32 { - self.x * other.x + self.y * other.y - } - - pub fn norm(&self) -> Vec2 { - let len = self.distance(); - Vec2 { - x: self.x / len, - y: self.y / len, - } - } -} - -#[derive(Clone, Copy, Debug)] -pub struct AABox { - pub pos: Vec2, - /// the size may not be smaller than zero - pub size: Vec2, -} - -impl std::ops::Add for AABox { - type Output = Self; - fn add(self, other: Vec2) -> Self { - Self { - pos: self.pos + other, - size: self.size, - } - } -} - -impl std::ops::AddAssign for AABox { - fn add_assign(&mut self, other: Vec2) { - self.pos += other - } -} - -impl std::ops::Sub for AABox { - type Output = Self; - fn sub(self, other: Vec2) -> Self { - Self { - pos: self.pos + other, - size: self.size - } - } -} - -impl std::ops::SubAssign for AABox { - fn sub_assign(&mut self, other: Vec2) { - self.pos -= other - } -} - -impl std::cmp::PartialEq for AABox { - fn eq(&self, other: &Self) -> bool { - self.pos == other.pos - && self.size == other.size - } -} - -impl std::cmp::Eq for AABox {} - -#[derive(Clone, Copy, Debug)] -pub struct RBox { - /// origin - pub pos: Vec2, - /// Vwctor1 - pub v1: Vec2, - /// Vector2 - pub v2: Vec2, -} - -impl RBox { - pub fn new(pos: Vec2, orientation: Vec2, width: f32) -> Self { - let scale = width / orientation.distance(); - let orth = Vec2 {x: orientation.x / scale, y: -orientation.y / scale}; - Self { - pos: pos, - v1: orientation, - v2: orth, - } - } -} - -impl std::ops::Add for RBox { - type Output = Self; - fn add(self, other: Vec2) -> Self { - Self { - pos: self.pos + other, - v1: self.v1, - v2: self.v2, - } - } -} - -impl std::ops::AddAssign for RBox { - fn add_assign(&mut self, other: Vec2) { - self.pos += other - } -} - -impl std::ops::Sub for RBox { - type Output = Self; - fn sub(self, other: Vec2) -> Self { - Self { - pos: self.pos + other, - v1: self.v1 + other, - v2: self.v2, - } - } -} - -impl std::ops::SubAssign for RBox { - fn sub_assign(&mut self, other: Vec2) { - self.pos -= other - } -} - -impl std::cmp::PartialEq for RBox { - fn eq(&self, other: &Self) -> bool { - self.pos == other.pos - && self.v1 == other.v1 - && self.v1 == self.v2 - } -} - -impl std::cmp::Eq for RBox {} - -#[cfg(test)] -mod tests { - // Note this useful idiom: importing names from outer (for mod tests) scope. - use super::*; - - #[test] - fn test_less_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -3.0, y: 2.5}; - - assert!(b < a); - } - - #[test] - fn test_less_vec2_fail() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: 3.0, y: 2.5}; - - assert!(!(a < b)); - } - - #[test] - fn test_greater_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -3.0, y: 2.5}; - - assert!(a > b); - } - - #[test] - fn test_greater_vec2_fail() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: 3.0, y: 2.5}; - - assert!(!(a > b)); - } - - - #[test] - fn test_add_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -3.0, y: 2.5}; - let c = Vec2{x: -2.0, y: 10.0}; - - assert_eq!(a + b, c); - } - - #[test] - fn test_neg_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -1.0, y: -7.5}; - - assert_eq!(-a, b); - } - - #[test] - fn test_sub_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -3.0, y: 2.5}; - let c = Vec2{x: 4.0, y: 5.0}; - - assert_eq!(a - b, c); - } - - #[test] - fn test_distance_vec2() { - let a = Vec2{x: 2.0, y: 2.0}; - - assert!(f32::abs(a.distance() - 2.0) < 1e8); - } - - #[test] - fn test_distance2_vec2() { - let a = Vec2{x: 1.0, y: 2.0}; - - assert!(f32::abs(a.distance2() - 5.0) < 1e8); - } - - #[test] - fn test_norm_vec2() { - let a = Vec2{x: 2.0, y: -2.0}; - let b = Vec2{x: std::f32::consts::FRAC_1_SQRT_2, y: -std::f32::consts::FRAC_1_SQRT_2}; - - assert_eq!(a.norm(), b); - } - - #[test] - fn test_add_aabox_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -3.0, y: 2.5}; - let mut aa_box = AABox{pos: a, size: b}; - let bb_box = AABox{pos: a + b,size: b}; - aa_box += b; - - assert_eq!(aa_box, bb_box); - } - - #[test] - fn test_sub_aabox_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -3.0, y: 2.5}; - let mut aa_box = AABox{pos: a, size: b}; - let bb_box = AABox{pos: a - b,size: b}; - aa_box -= b; - - assert_eq!(aa_box, bb_box); - } - - #[test] - fn test_add_rbox_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -3.0, y: 2.5}; - let c = Vec2{x: -3.0, y: 2.5}; - let mut aa_box = RBox{pos: a, v1: b, v2: c}; - let bb_box = RBox{pos: a + b, v1: b, v2: c}; - aa_box += b; - - assert_eq!(aa_box, bb_box); - } - - #[test] - fn test_sub_rbox_vec2() { - let a = Vec2{x: 1.0, y: 7.5}; - let b = Vec2{x: -3.0, y: 2.5}; - let c = Vec2{x: -3.0, y: 2.5}; - let mut aa_box = RBox{pos: a, v1: b, v2: c}; - let bb_box = RBox{pos: a - b, v1: b, v2: c}; - aa_box -= b; - - assert_eq!(aa_box, bb_box); - } -} -- cgit v1.2.3 From 36c89240a87ecb826cf09bc7b3069aa636c9f2f1 Mon Sep 17 00:00:00 2001 From: konsumlamm Date: Fri, 21 Jun 2019 20:56:58 +0200 Subject: update maths to math --- webhogg/game_server/src/collide.rs | 4 ++-- webhogg/game_server/src/main.rs | 2 +- webhogg/game_server/src/webhogg_game.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/webhogg/game_server/src/collide.rs b/webhogg/game_server/src/collide.rs index 16b5357..44ab311 100644 --- a/webhogg/game_server/src/collide.rs +++ b/webhogg/game_server/src/collide.rs @@ -1,4 +1,4 @@ -use crate::maths::{Vec2, AABox, RBox}; +use crate::math::{Vec2, AABox, RBox}; pub trait Collide { fn collides(&self, other: &Rhs) -> bool; @@ -12,7 +12,7 @@ impl Collide for Vec2 { impl Collide for AABox { fn collides(&self, other: &Vec2) -> bool { - self.pos < *other && other < &(self.pos + self.size) + self.pos < *other && other < &(self.pos + self.size) } } diff --git a/webhogg/game_server/src/main.rs b/webhogg/game_server/src/main.rs index cfd9787..2db757b 100644 --- a/webhogg/game_server/src/main.rs +++ b/webhogg/game_server/src/main.rs @@ -1,5 +1,5 @@ mod group; -mod maths; +mod math; mod scribble_group; mod webhogg_group; mod webhogg_game; diff --git a/webhogg/game_server/src/webhogg_game.rs b/webhogg/game_server/src/webhogg_game.rs index 7b94fcb..b3f35cc 100644 --- a/webhogg/game_server/src/webhogg_game.rs +++ b/webhogg/game_server/src/webhogg_game.rs @@ -1,4 +1,4 @@ -use crate::maths::Vec2; +use crate::math::Vec2; pub struct WebhoggPlayer { pos: Vec2, -- cgit v1.2.3 From 5522731ec4de8741f923b339ca942f8aaff2a338 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 21 Jun 2019 23:57:15 +0200 Subject: Fix changed Method names and minor compiler warnings --- webhogg/game_server/src/collide.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/webhogg/game_server/src/collide.rs b/webhogg/game_server/src/collide.rs index 44ab311..940cffd 100644 --- a/webhogg/game_server/src/collide.rs +++ b/webhogg/game_server/src/collide.rs @@ -25,8 +25,8 @@ impl Collide for AABox { impl Collide for RBox { fn collides(&self, other: &Vec2) -> bool { - let v1_diff = *other + self.v1 * (-self.v1.scalar(&(*other - self.pos)) / self.v1.distance2()); - let v2_diff = *other + self.v2 * (-self.v2.scalar(&(*other - self.pos)) / self.v2.distance2()); + let v1_diff = *other + self.v1 * (-self.v1.dot(&(*other - self.pos)) / self.v1.norm2()); + let v2_diff = *other + self.v2 * (-self.v2.dot(&(*other - self.pos)) / self.v2.norm2()); let v1_dist = ((v1_diff - self.pos) / self.v2).x; let v2_dist = ((v2_diff - self.pos) / self.v1).x; @@ -42,16 +42,16 @@ impl Collide for RBox { let other_size = other.pos + other.size; // project points onto a orthogonal line - let v1_diff = other.pos + self.v1 * (-self.v1.scalar(&(other.pos - self.pos)) / self.v1.distance2()); - let v2_diff = other.pos + self.v2 * (-self.v2.scalar(&other.pos) / self.v2.distance2()); - let v1_diff_size = other_size + self.v1 * (-self.v1.scalar(&(other_size - self.pos)) / self.v1.distance2()); - let v2_diff_size = other_size + self.v2 * (-self.v2.scalar(&(other_size - self.pos)) / self.v2.distance2()); + let v1_diff = other.pos + self.v1 * (-self.v1.dot(&(other.pos - self.pos)) / self.v1.norm2()); + let v2_diff = other.pos + self.v2 * (-self.v2.dot(&other.pos) / self.v2.norm2()); + let v1_diff_size = other_size + self.v1 * (-self.v1.dot(&(other_size - self.pos)) / self.v1.norm2()); + let v2_diff_size = other_size + self.v2 * (-self.v2.dot(&(other_size - self.pos)) / self.v2.norm2()); - // calculate the distance - let v1_dist = ((v1_diff - self.pos) / self.v2); - let v2_dist = ((v2_diff - self.pos) / self.v1); - let v1_dist_size = ((v1_diff_size - self.pos) / self.v2); - let v2_dist_size = ((v2_diff_size - self.pos) / self.v1); + // calculate the norm + let v1_dist = (v1_diff - self.pos) / self.v2; + let v2_dist = (v2_diff - self.pos) / self.v1; + let v1_dist_size = (v1_diff_size - self.pos) / self.v2; + let v2_dist_size = (v2_diff_size - self.pos) / self.v1; let v1_dist = if v1_dist.x.is_finite() {v1_dist.x} else {v1_dist.y}; let v2_dist = if v2_dist.x.is_finite() {v2_dist.x} else {v2_dist.y}; @@ -150,7 +150,7 @@ impl> Collide for Vec { } #[test] - fn test_collide_Rbox_dot() { + fn test_collide_rbox_dot() { let a = Vec2{x: 1.0, y: 1.0}; let b = Vec2{x: 1.0, y: 1.0}; let c = Vec2{x: 1.0, y: -1.0}; -- cgit v1.2.3