From 32426ac045a46c0fc4675264fe7ff24982761f50 Mon Sep 17 00:00:00 2001 From: Max Richter Date: Thu, 18 Apr 2024 13:16:33 +0200 Subject: [PATCH] feat: add vec3 to stem --- Cargo.lock | 137 +++----- .../lib/graph-interface/node/NodeInput.svelte | 4 +- .../graph-interface/node/NodeParameter.svelte | 308 ++++++++++-------- app/src/lib/node-registry.ts | 1 + app/src/lib/runtime-executor.ts | 9 +- nodes/max/plantarium/.template/.gitignore | 6 + nodes/max/plantarium/.template/Cargo.toml | 28 ++ nodes/max/plantarium/.template/package.json | 6 + nodes/max/plantarium/.template/src/input.json | 4 + nodes/max/plantarium/.template/src/lib.rs | 12 + nodes/max/plantarium/.template/tests/web.rs | 13 + nodes/max/plantarium/array/src/lib.rs | 9 +- nodes/max/plantarium/box/src/lib.rs | 11 +- nodes/max/plantarium/output/Cargo.toml | 1 + nodes/max/plantarium/output/src/lib.rs | 23 +- nodes/max/plantarium/stem/src/input.json | 9 + nodes/max/plantarium/stem/src/lib.rs | 18 +- nodes/max/plantarium/sum/Cargo.toml | 2 +- nodes/max/plantarium/triangle/Cargo.toml | 2 +- nodes/max/plantarium/vec3/.gitignore | 6 + nodes/max/plantarium/vec3/Cargo.toml | 28 ++ nodes/max/plantarium/vec3/package.json | 6 + nodes/max/plantarium/vec3/src/input.json | 16 + nodes/max/plantarium/vec3/src/lib.rs | 20 ++ nodes/max/plantarium/vec3/tests/web.rs | 13 + packages/utils/Cargo.toml | 1 - packages/utils/src/geometry/extrude_path.rs | 21 +- packages/utils/src/geometry/geometry.rs | 74 +++++ packages/utils/src/geometry/mod.rs | 32 +- packages/utils/src/geometry/transform.rs | 25 ++ packages/utils/src/tree.rs | 45 ++- 31 files changed, 563 insertions(+), 327 deletions(-) create mode 100644 nodes/max/plantarium/.template/.gitignore create mode 100644 nodes/max/plantarium/.template/Cargo.toml create mode 100644 nodes/max/plantarium/.template/package.json create mode 100644 nodes/max/plantarium/.template/src/input.json create mode 100644 nodes/max/plantarium/.template/src/lib.rs create mode 100644 nodes/max/plantarium/.template/tests/web.rs create mode 100644 nodes/max/plantarium/vec3/.gitignore create mode 100644 nodes/max/plantarium/vec3/Cargo.toml create mode 100644 nodes/max/plantarium/vec3/package.json create mode 100644 nodes/max/plantarium/vec3/src/input.json create mode 100644 nodes/max/plantarium/vec3/src/lib.rs create mode 100644 nodes/max/plantarium/vec3/tests/web.rs create mode 100644 packages/utils/src/geometry/geometry.rs create mode 100644 packages/utils/src/geometry/transform.rs diff --git a/Cargo.lock b/Cargo.lock index 72c45bc..7245610 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,26 +65,6 @@ dependencies = [ "wasm-bindgen-test", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gl_matrix" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df64d0245c589931a0b5a385a63e7db2aeff209bdd471df0417e0f230a4c33ae" -dependencies = [ - "rand", -] - [[package]] name = "glam" version = "0.27.0" @@ -106,12 +86,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - [[package]] name = "log" version = "0.4.21" @@ -141,6 +115,48 @@ dependencies = [ "web-sys", ] +[[package]] +name = "max-plantarium-sum" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "macros", + "serde", + "serde-wasm-bindgen", + "utils", + "wasm-bindgen", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "max-plantarium-triangle" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "macros", + "serde", + "serde-wasm-bindgen", + "utils", + "wasm-bindgen", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "max-plantarium-vec3" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "macros", + "serde", + "serde-wasm-bindgen", + "utils", + "wasm-bindgen", + "wasm-bindgen-test", + "web-sys", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -152,6 +168,7 @@ name = "output" version = "0.1.0" dependencies = [ "console_error_panic_hook", + "glam", "macros", "serde", "serde-wasm-bindgen", @@ -162,12 +179,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - [[package]] name = "proc-macro2" version = "1.0.80" @@ -186,47 +197,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - [[package]] name = "random" version = "0.1.0" @@ -308,20 +278,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "sum" -version = "0.1.0" -dependencies = [ - "console_error_panic_hook", - "macros", - "serde", - "serde-wasm-bindgen", - "utils", - "wasm-bindgen", - "wasm-bindgen-test", - "web-sys", -] - [[package]] name = "syn" version = "1.0.109" @@ -369,7 +325,6 @@ name = "utils" version = "0.1.0" dependencies = [ "console_error_panic_hook", - "gl_matrix", "glam", "serde", "serde_json", @@ -377,12 +332,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasm-bindgen" version = "0.2.92" diff --git a/app/src/lib/graph-interface/node/NodeInput.svelte b/app/src/lib/graph-interface/node/NodeInput.svelte index 75df924..ebc6a32 100644 --- a/app/src/lib/graph-interface/node/NodeInput.svelte +++ b/app/src/lib/graph-interface/node/NodeInput.svelte @@ -6,13 +6,12 @@ export let node: Node; export let input: NodeInput; export let id: string; - export let label: string | undefined; const graph = getGraphManager(); let value = node?.props?.[id] ?? input.value; - let elementId = Math.random().toString(36).substring(7); + export let elementId: string = `input-${Math.random().toString(36).substring(7)}`; $: if (node?.props?.[id] !== value) { node.props = { ...node.props, [id]: value }; @@ -21,5 +20,4 @@ } - diff --git a/app/src/lib/graph-interface/node/NodeParameter.svelte b/app/src/lib/graph-interface/node/NodeParameter.svelte index fd6e61b..4ecd040 100644 --- a/app/src/lib/graph-interface/node/NodeParameter.svelte +++ b/app/src/lib/graph-interface/node/NodeParameter.svelte @@ -1,174 +1,196 @@ -
- {#key id && graphId} - {#if node?.tmp?.type?.inputs?.[id]?.external !== true} -
- -
- {/if} +
+ {#key id && graphId} +
+ + {#if node?.tmp?.type?.inputs?.[id]?.external !== true} + + {/if} +
- {#if node?.tmp?.type?.inputs?.[id]?.internal !== true} -
-
- {/if} - {/key} + {#if node?.tmp?.type?.inputs?.[id]?.internal !== true} +
+
+ {/if} + {/key} - - - + > + +
diff --git a/app/src/lib/node-registry.ts b/app/src/lib/node-registry.ts index 9d259a5..45d14cb 100644 --- a/app/src/lib/node-registry.ts +++ b/app/src/lib/node-registry.ts @@ -73,6 +73,7 @@ export class RemoteNodeRegistry implements NodeRegistry { nodeIds.push("max/plantarium/random"); nodeIds.push("max/plantarium/float"); nodeIds.push("max/plantarium/triangle"); + nodeIds.push("max/plantarium/vec3"); nodeIds.push("max/plantarium/output"); nodeIds.push("max/plantarium/array"); nodeIds.push("max/plantarium/sum"); diff --git a/app/src/lib/runtime-executor.ts b/app/src/lib/runtime-executor.ts index 8d2dbc1..d05a945 100644 --- a/app/src/lib/runtime-executor.ts +++ b/app/src/lib/runtime-executor.ts @@ -1,5 +1,5 @@ import type { Graph, NodeRegistry, NodeType, RuntimeExecutor } from "@nodes/types"; -import { fastHash, concat_encoded, encodeFloat } from "@nodes/utils" +import { fastHash, concat_encoded, encodeFloat, encode } from "@nodes/utils" export class MemoryRuntimeExecutor implements RuntimeExecutor { @@ -176,15 +176,22 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor { return encodeFloat(value as number); } + if (Array.isArray(value)) { + return encode(value); + } + return value; }); + console.log(transformed_inputs); + const a2 = performance.now(); // console.log(`${a2 - a1}ms TRANSFORMED_INPUTS`); const _inputs = concat_encoded(transformed_inputs); const a3 = performance.now(); + console.log(`executing ${node_type.id || node.id}`, _inputs); results[node.id] = node_type.execute(_inputs) as number; const duration = performance.now() - a3; if (duration > 5) { diff --git a/nodes/max/plantarium/.template/.gitignore b/nodes/max/plantarium/.template/.gitignore new file mode 100644 index 0000000..4e30131 --- /dev/null +++ b/nodes/max/plantarium/.template/.gitignore @@ -0,0 +1,6 @@ +/target +**/*.rs.bk +Cargo.lock +bin/ +pkg/ +wasm-pack.log diff --git a/nodes/max/plantarium/.template/Cargo.toml b/nodes/max/plantarium/.template/Cargo.toml new file mode 100644 index 0000000..2b724c9 --- /dev/null +++ b/nodes/max/plantarium/.template/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "triangle" +version = "0.1.0" +authors = ["Max Richter "] +edition = "2018" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["console_error_panic_hook"] + +[dependencies] +wasm-bindgen = "0.2.84" + +# 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. +utils = { version = "0.1.0", path = "../../../../packages/utils" } +macros = { version = "0.1.0", path = "../../../../packages/macros" } +serde = { version = "1.0", features = ["derive"] } +serde-wasm-bindgen = "0.4" +console_error_panic_hook = { version = "0.1.7", optional = true } +web-sys = { version = "0.3.69", features = ["console"] } + +[dev-dependencies] +wasm-bindgen-test = "0.3.34" diff --git a/nodes/max/plantarium/.template/package.json b/nodes/max/plantarium/.template/package.json new file mode 100644 index 0000000..a601fc9 --- /dev/null +++ b/nodes/max/plantarium/.template/package.json @@ -0,0 +1,6 @@ +{ + "scripts": { + "build": "wasm-pack build --release --out-name index --no-default-features", + "dev": "cargo watch -s 'pnpm build'" + } +} diff --git a/nodes/max/plantarium/.template/src/input.json b/nodes/max/plantarium/.template/src/input.json new file mode 100644 index 0000000..0384747 --- /dev/null +++ b/nodes/max/plantarium/.template/src/input.json @@ -0,0 +1,4 @@ +{ + "outputs": [], + "inputs": {} +} diff --git a/nodes/max/plantarium/.template/src/lib.rs b/nodes/max/plantarium/.template/src/lib.rs new file mode 100644 index 0000000..3dbc453 --- /dev/null +++ b/nodes/max/plantarium/.template/src/lib.rs @@ -0,0 +1,12 @@ +use macros::include_definition_file; +use utils::{decode_float, encode_float, wrap_arg}; +use wasm_bindgen::prelude::*; +use web_sys::console; + +include_definition_file!("src/input.json"); + +#[rustfmt::skip] +#[wasm_bindgen] +pub fn execute(input: &[i32]) -> Vec { + vec![] +} diff --git a/nodes/max/plantarium/.template/tests/web.rs b/nodes/max/plantarium/.template/tests/web.rs new file mode 100644 index 0000000..de5c1da --- /dev/null +++ b/nodes/max/plantarium/.template/tests/web.rs @@ -0,0 +1,13 @@ +//! Test suite for the Web and headless browsers. + +#![cfg(target_arch = "wasm32")] + +extern crate wasm_bindgen_test; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); + +#[wasm_bindgen_test] +fn pass() { + assert_eq!(1 + 1, 2); +} diff --git a/nodes/max/plantarium/array/src/lib.rs b/nodes/max/plantarium/array/src/lib.rs index 0179024..78be6f1 100644 --- a/nodes/max/plantarium/array/src/lib.rs +++ b/nodes/max/plantarium/array/src/lib.rs @@ -1,5 +1,5 @@ use macros::include_definition_file; -use utils::{evaluate_args, get_args}; +use utils::{evaluate_arg, get_args}; use wasm_bindgen::prelude::*; use web_sys::console; @@ -11,9 +11,8 @@ pub fn execute(input: &[i32]) -> Vec { let args = get_args(input); - let value_encoded = evaluate_args(args[0]); - // let value = decode_float(value_encoded[0], value_encoded[1]); - let length = (args[1][0]) as usize; + let value_encoded = evaluate_arg(args[0]); + let length = evaluate_arg(args[1]) as usize; console::log_1(&format!("WASM(array): input: {:?} -> {:?}", args, value_encoded).into()); @@ -22,7 +21,7 @@ pub fn execute(input: &[i32]) -> Vec { res.push(0); res.push(length as i32 + 4); for _ in 0..length { - res.push(value_encoded[0]); + res.push(value_encoded); } res.push(1); res.push(1); diff --git a/nodes/max/plantarium/box/src/lib.rs b/nodes/max/plantarium/box/src/lib.rs index 443d37c..5183167 100644 --- a/nodes/max/plantarium/box/src/lib.rs +++ b/nodes/max/plantarium/box/src/lib.rs @@ -1,7 +1,6 @@ -use crate::geometry::calculate_normals; use macros::include_definition_file; use utils::{ - decode_float, encode_float, evaluate_args, geometry, get_args, set_panic_hook, wrap_arg, + encode_float, evaluate_float, geometry::calculate_normals, get_args, set_panic_hook, wrap_arg, }; use wasm_bindgen::prelude::*; use web_sys::console; @@ -18,12 +17,10 @@ pub fn execute(input: &[i32]) -> Vec { console::log_1(&format!("WASM(cube): input: {:?} -> {:?}", input, args ).into()); - let arg1 = evaluate_args(args[0]); + let size = evaluate_float(args[0]); - let decoded = decode_float(arg1[0]); - - let p = encode_float(decoded); - let n = encode_float(-decoded); + let p = encode_float(size); + let n = encode_float(-size); // [[1,3, x, y, z, x, y,z,x,y,z]]; diff --git a/nodes/max/plantarium/output/Cargo.toml b/nodes/max/plantarium/output/Cargo.toml index ace99c4..9c553e7 100644 --- a/nodes/max/plantarium/output/Cargo.toml +++ b/nodes/max/plantarium/output/Cargo.toml @@ -25,6 +25,7 @@ macros = { version = "0.1.0", path = "../../../../packages/macros" } serde-wasm-bindgen = "0.4" console_error_panic_hook = { version = "0.1.7", optional = true } web-sys = { version = "0.3.69", features = ["console"] } +glam = "0.27.0" [dev-dependencies] wasm-bindgen-test = "0.3.34" diff --git a/nodes/max/plantarium/output/src/lib.rs b/nodes/max/plantarium/output/src/lib.rs index 7278977..43f96e4 100644 --- a/nodes/max/plantarium/output/src/lib.rs +++ b/nodes/max/plantarium/output/src/lib.rs @@ -1,31 +1,36 @@ +use glam::{Mat4, Vec3}; use macros::include_definition_file; -use utils::{concat_args, geometry::extrude_path, get_args}; +use utils::{ + concat_args, + geometry::{extrude_path, transform_geometry}, + get_args, +}; use wasm_bindgen::prelude::*; include_definition_file!("src/inputs.json"); -#[rustfmt::skip] #[wasm_bindgen] pub fn execute(input: Vec) -> Vec { utils::set_panic_hook(); let args = get_args(input.as_slice()); - let mut output:Vec> = Vec::new(); + let mut output: Vec> = Vec::new(); for arg in args { - - if arg.len() < 3 { continue; } + if arg.len() < 3 { + continue; + } if arg[2] == 0 { let _arg = &arg[3..]; - let geometry = extrude_path(_arg, 16); + let mut geometry = extrude_path(_arg, 4); + let matrix = Mat4::from_translation(Vec3::new(0.0, 0.0, 0.0)); + geometry = transform_geometry(geometry, matrix); output.push(geometry); - }else if arg[2] == 1 { + } else if arg[2] == 1 { output.push(arg.to_vec()); } - } concat_args(output) - } diff --git a/nodes/max/plantarium/stem/src/input.json b/nodes/max/plantarium/stem/src/input.json index 5d6a7d1..a94039d 100644 --- a/nodes/max/plantarium/stem/src/input.json +++ b/nodes/max/plantarium/stem/src/input.json @@ -3,6 +3,15 @@ "plant" ], "inputs": { + "origin": { + "type": "vec3", + "value": [ + 0, + 0, + 0 + ], + "external": true + }, "length": { "type": "float", "value": 2 diff --git a/nodes/max/plantarium/stem/src/lib.rs b/nodes/max/plantarium/stem/src/lib.rs index ff37ad0..0b5e367 100644 --- a/nodes/max/plantarium/stem/src/lib.rs +++ b/nodes/max/plantarium/stem/src/lib.rs @@ -1,5 +1,5 @@ use macros::include_definition_file; -use utils::{decode_float, evaluate_args, get_args, set_panic_hook, wrap_arg}; +use utils::{evaluate_float, evaluate_vec3, get_args, log, set_panic_hook, wrap_arg}; use wasm_bindgen::prelude::*; include_definition_file!("src/input.json"); @@ -10,9 +10,13 @@ pub fn execute(input: &[i32]) -> Vec { let args = get_args(input); - let length = decode_float(evaluate_args(args[0])[0]); - let thickness = decode_float(evaluate_args(args[1])[0]); - let resolution = 512; //evaluate_args(args[2]); + log!("Args: {:?}", args); + + let origin = evaluate_vec3(args[0]); + log!("Origin: {:?}", origin); + let length = evaluate_float(args[1]); + let thickness = evaluate_float(args[2]); + let resolution = 16; let mut path: Vec = vec![0; resolution * 4 + 1]; path.resize(resolution * 4 + 1, 0); @@ -32,9 +36,9 @@ pub fn execute(input: &[i32]) -> Vec { for i in 0..resolution { let a = i as f32 / resolution as f32; - path_p[i * 4] = (a * 8.0).sin() * 0.2; - path_p[i * 4 + 1] = a * length; - path_p[i * 4 + 2] = 0.0; + path_p[i * 4] = origin[0] + (a * 8.0).sin() * 0.2; + path_p[i * 4 + 1] = origin[1] + a * length; + path_p[i * 4 + 2] = origin[2] + 0.0; path_p[i * 4 + 3] = thickness * (1.0 - a); } diff --git a/nodes/max/plantarium/sum/Cargo.toml b/nodes/max/plantarium/sum/Cargo.toml index c72548b..d344d8f 100644 --- a/nodes/max/plantarium/sum/Cargo.toml +++ b/nodes/max/plantarium/sum/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sum" +name = "max-plantarium-sum" version = "0.1.0" authors = ["Max Richter "] edition = "2018" diff --git a/nodes/max/plantarium/triangle/Cargo.toml b/nodes/max/plantarium/triangle/Cargo.toml index 2b724c9..2f6518a 100644 --- a/nodes/max/plantarium/triangle/Cargo.toml +++ b/nodes/max/plantarium/triangle/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "triangle" +name = "max-plantarium-triangle" version = "0.1.0" authors = ["Max Richter "] edition = "2018" diff --git a/nodes/max/plantarium/vec3/.gitignore b/nodes/max/plantarium/vec3/.gitignore new file mode 100644 index 0000000..4e30131 --- /dev/null +++ b/nodes/max/plantarium/vec3/.gitignore @@ -0,0 +1,6 @@ +/target +**/*.rs.bk +Cargo.lock +bin/ +pkg/ +wasm-pack.log diff --git a/nodes/max/plantarium/vec3/Cargo.toml b/nodes/max/plantarium/vec3/Cargo.toml new file mode 100644 index 0000000..fed1e0d --- /dev/null +++ b/nodes/max/plantarium/vec3/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "max-plantarium-vec3" +version = "0.1.0" +authors = ["Max Richter "] +edition = "2018" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["console_error_panic_hook"] + +[dependencies] +wasm-bindgen = "0.2.84" + +# 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. +utils = { version = "0.1.0", path = "../../../../packages/utils" } +macros = { version = "0.1.0", path = "../../../../packages/macros" } +serde = { version = "1.0", features = ["derive"] } +serde-wasm-bindgen = "0.4" +console_error_panic_hook = { version = "0.1.7", optional = true } +web-sys = { version = "0.3.69", features = ["console"] } + +[dev-dependencies] +wasm-bindgen-test = "0.3.34" diff --git a/nodes/max/plantarium/vec3/package.json b/nodes/max/plantarium/vec3/package.json new file mode 100644 index 0000000..a601fc9 --- /dev/null +++ b/nodes/max/plantarium/vec3/package.json @@ -0,0 +1,6 @@ +{ + "scripts": { + "build": "wasm-pack build --release --out-name index --no-default-features", + "dev": "cargo watch -s 'pnpm build'" + } +} diff --git a/nodes/max/plantarium/vec3/src/input.json b/nodes/max/plantarium/vec3/src/input.json new file mode 100644 index 0000000..ec5bba4 --- /dev/null +++ b/nodes/max/plantarium/vec3/src/input.json @@ -0,0 +1,16 @@ +{ + "outputs": [ + "vec3" + ], + "inputs": { + "0": { + "type": "float" + }, + "1": { + "type": "float" + }, + "2": { + "type": "float" + } + } +} diff --git a/nodes/max/plantarium/vec3/src/lib.rs b/nodes/max/plantarium/vec3/src/lib.rs new file mode 100644 index 0000000..f97c101 --- /dev/null +++ b/nodes/max/plantarium/vec3/src/lib.rs @@ -0,0 +1,20 @@ +use macros::include_definition_file; +use utils::log; +use wasm_bindgen::prelude::*; + +include_definition_file!("src/input.json"); + +#[wasm_bindgen] +pub fn execute(args: &[i32]) -> Vec { + let mut result = Vec::with_capacity(args.len() + 2); + result.push(0); // encoding the [ bracket + result.push(args[1]); + + result.extend_from_slice(&args[2..]); + + result.push(1); + result.push(1); // closing bracket + + log!("WASM(vec3): res {:?}", result); + result +} diff --git a/nodes/max/plantarium/vec3/tests/web.rs b/nodes/max/plantarium/vec3/tests/web.rs new file mode 100644 index 0000000..de5c1da --- /dev/null +++ b/nodes/max/plantarium/vec3/tests/web.rs @@ -0,0 +1,13 @@ +//! Test suite for the Web and headless browsers. + +#![cfg(target_arch = "wasm32")] + +extern crate wasm_bindgen_test; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); + +#[wasm_bindgen_test] +fn pass() { + assert_eq!(1 + 1, 2); +} diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index d51cef1..96eb7e4 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -12,5 +12,4 @@ web-sys = { version = "0.3.69", features = ["console"] } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } console_error_panic_hook = { version = "0.1.7", optional = true } -gl_matrix = "0.0.2" glam = "0.27.0" diff --git a/packages/utils/src/geometry/extrude_path.rs b/packages/utils/src/geometry/extrude_path.rs index 27e3301..19830dc 100644 --- a/packages/utils/src/geometry/extrude_path.rs +++ b/packages/utils/src/geometry/extrude_path.rs @@ -1,4 +1,4 @@ -use super::create_empty_geometry; +use super::{create_geometry_data, wrap_geometry_data}; use glam::{Mat4, Quat, Vec3}; fn create_circle(res: usize) -> Vec { @@ -19,22 +19,19 @@ pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec { let circle = create_circle(res_x); - let mut geometry = create_empty_geometry(vertices_amount, face_amount); + let mut geometry_data = create_geometry_data(vertices_amount, face_amount); + + let geometry = wrap_geometry_data(&mut geometry_data); + + let normals = geometry.normals; + let positions = geometry.positions; + let indices = geometry.faces; - let (_header,rest) = geometry.split_at_mut(5); - let (indices, rest) = rest.split_at_mut(face_amount*3); - let (_positions, _normals) = rest.split_at_mut(vertices_amount*3); - let positions: &mut [f32]; - let normals: &mut [f32]; let path: &[f32]; unsafe { path = std::slice::from_raw_parts(input_path.as_ptr() as *const f32, input_path.len()); - positions = std::slice::from_raw_parts_mut(_positions.as_mut_ptr() as *mut f32, _positions.len()); - normals = std::slice::from_raw_parts_mut(_normals.as_mut_ptr() as *mut f32, _normals.len()); } - normals[0] = 0.0; - for i in 0..point_amount { let index_offset = i * res_x * 6; @@ -109,5 +106,5 @@ pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec { } } - geometry + geometry_data } diff --git a/packages/utils/src/geometry/geometry.rs b/packages/utils/src/geometry/geometry.rs new file mode 100644 index 0000000..f10d1cc --- /dev/null +++ b/packages/utils/src/geometry/geometry.rs @@ -0,0 +1,74 @@ +use crate::log; + +pub struct GeometryData<'a> { + pub positions: &'a mut [f32], // View into `data` + pub normals: &'a mut [f32], // View into `data` + pub faces: &'a mut [i32], // View into `data` +} + +pub fn create_geometry_data(vertex_amount: usize, face_amount: usize) -> Vec { + let amount = 3 // definition (type, vertex_amount, face_amount) + + 4 // opening and closing brackets + + vertex_amount * 3 // positions + + vertex_amount * 3 // normals + + face_amount * 3; // faces + + let mut geo = vec![0; amount]; + + geo[0] = 0; // opening bracket + geo[1] = amount as i32 - 2; // opening bracket + geo[2] = 1; // type: geometry + geo[3] = vertex_amount as i32; + geo[4] = face_amount as i32; + geo[amount - 2] = 1; // closing bracket + geo[amount - 1] = 1; // closing bracket + + geo +} + +pub fn wrap_geometry_data(geometry: &mut [i32]) -> GeometryData { + // Basic validity checks + assert!( + geometry.len() > 5, + "Geometry vector does not contain enough data for a header." + ); + + // Split at after header + let (header, rest) = geometry.split_at_mut(5); + + let vertices_amount = header[3] as usize; + let face_amount = header[4] as usize; + let total_floats = vertices_amount * 3 * 2; + + let (faces, rest) = rest.split_at_mut(face_amount * 3); + let (positions_slice, rest) = rest.split_at_mut(vertices_amount * 3); + let (normals_slice, _) = rest.split_at_mut(vertices_amount * 3); + + log!( + "Vertices: {}, normals: {}, Total floats: {}", + positions_slice.len(), + normals_slice.len(), + total_floats + ); + + assert!( + positions_slice.len() + normals_slice.len() == total_floats, + "Slices do not match the expected sizes." + ); + + let positions: &mut [f32] = unsafe { + std::slice::from_raw_parts_mut( + positions_slice.as_mut_ptr() as *mut f32, + positions_slice.len(), + ) + }; + let normals: &mut [f32] = unsafe { + std::slice::from_raw_parts_mut(normals_slice.as_mut_ptr() as *mut f32, normals_slice.len()) + }; + + GeometryData { + positions, + normals, + faces, + } +} diff --git a/packages/utils/src/geometry/mod.rs b/packages/utils/src/geometry/mod.rs index c499d2f..9efe85a 100644 --- a/packages/utils/src/geometry/mod.rs +++ b/packages/utils/src/geometry/mod.rs @@ -1,33 +1,9 @@ mod calculate_normals; mod extrude_path; +mod geometry; +mod transform; pub use calculate_normals::*; pub use extrude_path::*; - -use crate::log; - -#[rustfmt::skip] -pub fn create_empty_geometry(vertex_amount: usize, face_amount: usize) -> Vec { - log!( - "create_empty_geometry: vertex_amount: {}, face_amount: {}", - vertex_amount, - face_amount - ); - - let amount = - 3 // definition (type, vertex_amount, face_amount) - + 4 // opening and closing brackets - + vertex_amount * 3 // positions - + vertex_amount * 3 // normals - + face_amount * 3; // faces - - let mut vec: Vec = vec![0; amount]; - vec[0] = 0; // opening bracket - vec[1] = amount as i32 - 2; // opening bracket - vec[2] = 1; // type: geometry - vec[3] = vertex_amount as i32; - vec[4] = face_amount as i32; - vec[amount - 2] = 1; // closing bracket - vec[amount - 1] = 1; // closing bracket - vec -} +pub use geometry::*; +pub use transform::*; diff --git a/packages/utils/src/geometry/transform.rs b/packages/utils/src/geometry/transform.rs new file mode 100644 index 0000000..607e3cc --- /dev/null +++ b/packages/utils/src/geometry/transform.rs @@ -0,0 +1,25 @@ +use glam::{Mat4, Vec3}; + +pub fn transform_geometry(mut geometry: Vec, matrix: Mat4) -> Vec { + let (_header, rest) = geometry.split_at_mut(5); + + let vertices_amount = _header[3] as usize; + let face_amount = _header[4] as usize; + + let (_indices, rest) = rest.split_at_mut(face_amount * 3); + let (_positions, _normals) = rest.split_at_mut(vertices_amount * 3); + let positions: &mut [f32]; + unsafe { + positions = + std::slice::from_raw_parts_mut(_positions.as_mut_ptr() as *mut f32, _positions.len()); + } + + for i in 0..vertices_amount { + let pos = Mat4::transform_point3(&matrix, Vec3::from_slice(&positions[i * 3..i * 3 + 3])); + positions[i * 3] = pos.x; + positions[i * 3 + 1] = pos.y; + positions[i * 3 + 2] = pos.z; + } + + geometry +} diff --git a/packages/utils/src/tree.rs b/packages/utils/src/tree.rs index c564cba..15184ed 100644 --- a/packages/utils/src/tree.rs +++ b/packages/utils/src/tree.rs @@ -1,3 +1,5 @@ +use crate::decode_float; + pub fn get_args(args: &[i32]) -> Vec<&[i32]> { let mut idx: usize = 0; let mut depth = -1; @@ -105,13 +107,29 @@ pub fn evaluate_node(input_args: &[i32]) -> i32 { } } -pub fn evaluate_args(input_args: &[i32]) -> Vec { - if input_args.len() == 1 { - return input_args.to_vec(); - } +pub fn evaluate_vec3(input_args: &[i32]) -> Vec { + let args = get_args(input_args); - if input_args.len() == 4 && input_args[0] == 0 && input_args[1] == 3 { - return vec![input_args[2], input_args[3]]; + assert!( + args.len() == 3, + "Failed to evaluate Vec3 - Expected 3 arguments, got {}", + args.len() + ); + + let x = evaluate_float(args[0]); + let y = evaluate_float(args[1]); + let z = evaluate_float(args[2]); + + vec![x, y, z] +} + +pub fn evaluate_float(arg: &[i32]) -> f32 { + decode_float(evaluate_arg(arg)) +} + +pub fn evaluate_arg(input_args: &[i32]) -> i32 { + if input_args.len() == 1 { + return input_args.to_vec()[0]; } let args = get_args(input_args); @@ -125,22 +143,20 @@ pub fn evaluate_args(input_args: &[i32]) -> Vec { resolved.push(arg[2]); resolved.push(arg[3]); } else { - resolved.push(evaluate_args(arg)[0]); + resolved.push(evaluate_arg(arg)); } } if resolved.len() > 1 { - let res = evaluate_node(&resolved); - vec![res] + evaluate_node(&resolved) } else { - resolved + resolved[0] } } + #[cfg(test)] mod tests { - use crate::encoding::decode_float; - use super::*; #[test] @@ -152,10 +168,9 @@ mod tests { // and another math node that adds 2 to that result // the numbers are f32 floats encoded as two i32's - let result = evaluate_args(&input); - let decoded = decode_float(result[0]); + let result = evaluate_float(&input); - assert_eq!(decoded, 6.0); + assert_eq!(result, 6.0); } #[test]