diff --git a/Cargo.lock b/Cargo.lock
index 6302ff8..7e07be8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,7 +3,13 @@
version = 3
[[package]]
-name = "array"
+name = "autocfg"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
+
+[[package]]
+name = "box"
version = "0.1.0"
dependencies = [
"console_error_panic_hook",
@@ -17,16 +23,11 @@ dependencies = [
]
[[package]]
-name = "autocfg"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
-
-[[package]]
-name = "box"
+name = "branch"
version = "0.1.0"
dependencies = [
"console_error_panic_hook",
+ "glam",
"macros",
"serde",
"serde-wasm-bindgen",
@@ -123,20 +124,6 @@ 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"
@@ -367,20 +354,6 @@ dependencies = [
"unicode-ident",
]
-[[package]]
-name = "template"
-version = "0.1.0"
-dependencies = [
- "console_error_panic_hook",
- "macros",
- "serde",
- "serde-wasm-bindgen",
- "utils",
- "wasm-bindgen",
- "wasm-bindgen-test",
- "web-sys",
-]
-
[[package]]
name = "types"
version = "0.1.0"
diff --git a/app/src/lib/result-viewer/Scene.svelte b/app/src/lib/result-viewer/Scene.svelte
index 99f228f..4ca8879 100644
--- a/app/src/lib/result-viewer/Scene.svelte
+++ b/app/src/lib/result-viewer/Scene.svelte
@@ -7,7 +7,6 @@
useTexture,
} from "@threlte/extras";
import {
- Texture,
type BufferGeometry,
type PerspectiveCamera,
type Vector3,
@@ -16,7 +15,6 @@
import { OrbitControls } from "@threlte/extras";
import { AppSettings } from "../settings/app-settings";
import localStore from "$lib/helpers/localStore";
- import { Inspector } from "three-inspect";
export let geometries: BufferGeometry[];
export let lines: Vector3[][];
@@ -89,13 +87,9 @@
{/if}
{#await matcap then value}
-
+
{#if false}
-
+
{/if}
{/await}
diff --git a/app/src/lib/settings/panels/ActiveNode.svelte b/app/src/lib/settings/panels/ActiveNode.svelte
index a0a5d1e..531fb97 100644
--- a/app/src/lib/settings/panels/ActiveNode.svelte
+++ b/app/src/lib/settings/panels/ActiveNode.svelte
@@ -64,11 +64,17 @@
{#if node}
- {#if nodeDefinition && store && Object.keys(nodeDefinition).length > 0}
-
- {:else}
-
Active Node has no Settings
- {/if}
+ {#key node.id}
+ {#if nodeDefinition && store && Object.keys(nodeDefinition).length > 0}
+
+ {:else}
+ Active Node has no Settings
+ {/if}
+ {/key}
{:else}
No active node
{/if}
diff --git a/app/src/routes/+page.svelte b/app/src/routes/+page.svelte
index 47c8f99..850eff3 100644
--- a/app/src/routes/+page.svelte
+++ b/app/src/routes/+page.svelte
@@ -49,10 +49,25 @@
let keymap: ReturnType;
function handleResult(event: CustomEvent) {
- res = runtimeExecutor.execute(event.detail, get(settings?.graph?.settings));
+ try {
+ res = runtimeExecutor.execute(
+ event.detail,
+ get(settingPanels?.graph?.settings),
+ );
+ } catch (error) {
+ console.log("errors", error);
+ }
if ($AppSettings.centerCamera && viewerCamera && viewerCenter) {
- viewerControls.target.copy(viewerCenter);
+ if (
+ Number.isNaN(viewerCenter.x) ||
+ Number.isNaN(viewerCenter.y) ||
+ Number.isNaN(viewerCenter.z)
+ ) {
+ // viewerCenter.set(0, 0, 0);
+ } else {
+ viewerControls.target.copy(viewerCenter);
+ }
viewerControls.update();
}
}
@@ -61,7 +76,7 @@
localStorage.setItem("graph", JSON.stringify(event.detail));
}
- let settings: Record = {
+ let settingPanels: Record = {
general: {
id: "general",
icon: "i-tabler-settings",
@@ -90,33 +105,33 @@
};
$: if (keymap) {
- settings.shortcuts = {
+ settingPanels.shortcuts = {
id: "shortcuts",
icon: "i-tabler-keyboard",
props: { keymap },
component: Keymap,
};
- settings = settings;
+ settingPanels = settingPanels;
}
$: if (manager) {
- settings.activeNode.props.manager = manager;
- settings.nodeStore = {
+ settingPanels.activeNode.props.manager = manager;
+ settingPanels.nodeStore = {
id: "Node Store",
icon: "i-tabler-database",
props: { nodeRegistry, manager },
component: NodeStore,
};
- settings = settings;
+ settingPanels = settingPanels;
}
$: if (activeNode) {
- settings.activeNode.props.node = activeNode;
- settings = settings;
+ settingPanels.activeNode.props.node = activeNode;
+ settingPanels = settingPanels;
} else {
- settings.activeNode.props.node = undefined;
- settings = settings;
+ settingPanels.activeNode.props.node = undefined;
+ settingPanels = settingPanels;
}
function handleSettings(
@@ -125,25 +140,25 @@
types: Record;
}>,
) {
- settings.general.definition.debug.stressTest.loadGrid.callback =
+ settingPanels.general.definition.debug.stressTest.loadGrid.callback =
function () {
- const store = get(settings.general.settings);
+ const store = get(settingPanels.general.settings);
graph = templates.grid(store.amount, store.amount);
};
- settings.general.definition.debug.stressTest.loadTree.callback =
+ settingPanels.general.definition.debug.stressTest.loadTree.callback =
function () {
- const store = get(settings.general.settings);
+ const store = get(settingPanels.general.settings);
graph = templates.tree(store.amount);
};
- settings.graph.settings = writable(ev.detail.values);
- settings.graph.definition = {
- ...settings.graph.definition,
+ settingPanels.graph.settings = writable(ev.detail.values);
+ settingPanels.graph.definition = {
+ ...settingPanels.graph.definition,
...ev.detail.types,
};
- settings = settings;
+ settingPanels = settingPanels;
}
@@ -168,12 +183,12 @@
bind:keymap
showGrid={$AppSettings?.showNodeGrid}
snapToGrid={$AppSettings?.snapToGrid}
- settings={settings?.graph?.settings}
+ settings={settingPanels?.graph?.settings}
on:settings={handleSettings}
on:result={handleResult}
on:save={handleSave}
/>
-
+
{/key}
diff --git a/nodes/max/plantarium/array/src/input.json b/nodes/max/plantarium/array/src/input.json
deleted file mode 100644
index 27cf31a..0000000
--- a/nodes/max/plantarium/array/src/input.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "id": "max/plantarium/array",
- "outputs": [
- "float"
- ],
- "inputs": {
- "value": {
- "type": "float",
- "value": 4.2
- },
- "amount": {
- "type": "integer",
- "value": 2
- }
- }
-}
diff --git a/nodes/max/plantarium/array/src/lib.rs b/nodes/max/plantarium/array/src/lib.rs
deleted file mode 100644
index 01f0158..0000000
--- a/nodes/max/plantarium/array/src/lib.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use macros::include_definition_file;
-use utils::{evaluate_int, get_args};
-use wasm_bindgen::prelude::*;
-use web_sys::console;
-
-include_definition_file!("src/input.json");
-
-#[wasm_bindgen]
-pub fn execute(input: &[i32]) -> Vec {
- utils::set_panic_hook();
-
- let args = get_args(input);
-
- let value_encoded = evaluate_int(args[0]);
- let length = evaluate_int(args[1]) as usize;
-
- console::log_1(&format!("WASM(array): input: {:?} -> {:?}", args, value_encoded).into());
-
- // construct array of length
- let mut res: Vec = Vec::with_capacity(length + 4);
- res.push(0);
- res.push(length as i32 + 4);
- for _ in 0..length {
- res.push(value_encoded);
- }
- res.push(1);
- res.push(1);
-
- res
-}
diff --git a/nodes/max/plantarium/box/src/lib.rs b/nodes/max/plantarium/box/src/lib.rs
index 5183167..954edc0 100644
--- a/nodes/max/plantarium/box/src/lib.rs
+++ b/nodes/max/plantarium/box/src/lib.rs
@@ -1,6 +1,6 @@
use macros::include_definition_file;
use utils::{
- encode_float, evaluate_float, geometry::calculate_normals, get_args, set_panic_hook, wrap_arg,
+ encode_float, evaluate_float, geometry::calculate_normals, set_panic_hook, split_args, wrap_arg,
};
use wasm_bindgen::prelude::*;
use web_sys::console;
@@ -13,7 +13,7 @@ pub fn execute(input: &[i32]) -> Vec {
set_panic_hook();
- let args = get_args(input);
+ let args = split_args(input);
console::log_1(&format!("WASM(cube): input: {:?} -> {:?}", input, args ).into());
diff --git a/nodes/max/plantarium/array/.gitignore b/nodes/max/plantarium/branch/.gitignore
similarity index 100%
rename from nodes/max/plantarium/array/.gitignore
rename to nodes/max/plantarium/branch/.gitignore
diff --git a/nodes/max/plantarium/array/Cargo.toml b/nodes/max/plantarium/branch/Cargo.toml
similarity index 96%
rename from nodes/max/plantarium/array/Cargo.toml
rename to nodes/max/plantarium/branch/Cargo.toml
index 7387ce3..a2f94b1 100644
--- a/nodes/max/plantarium/array/Cargo.toml
+++ b/nodes/max/plantarium/branch/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "array"
+name = "branch"
version = "0.1.0"
authors = ["Max Richter "]
edition = "2018"
@@ -19,10 +19,11 @@ wasm-bindgen = "0.2.84"
# code size when deploying.
utils = { version = "0.1.0", path = "../../../../packages/utils" }
macros = { version = "0.1.0", path = "../../../../packages/macros" }
-web-sys = { version = "0.3.69", features = ["console"] }
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"] }
+glam = "0.27.0"
[dev-dependencies]
wasm-bindgen-test = "0.3.34"
diff --git a/nodes/max/plantarium/array/package.json b/nodes/max/plantarium/branch/package.json
similarity index 100%
rename from nodes/max/plantarium/array/package.json
rename to nodes/max/plantarium/branch/package.json
diff --git a/nodes/max/plantarium/branches/src/input.json b/nodes/max/plantarium/branch/src/input.json
similarity index 96%
rename from nodes/max/plantarium/branches/src/input.json
rename to nodes/max/plantarium/branch/src/input.json
index e7e4eba..74cc454 100644
--- a/nodes/max/plantarium/branches/src/input.json
+++ b/nodes/max/plantarium/branch/src/input.json
@@ -15,7 +15,7 @@
"step": 0.05,
"value": 0.8
},
- "thiccness": {
+ "thickness": {
"type": "float",
"min": 0,
"max": 1,
@@ -47,7 +47,7 @@
"value": 1
},
"depth": {
- "type": "float",
+ "type": "integer",
"hidden": true,
"min": 1,
"value": 1,
diff --git a/nodes/max/plantarium/branch/src/lib.rs b/nodes/max/plantarium/branch/src/lib.rs
new file mode 100644
index 0000000..30b5b46
--- /dev/null
+++ b/nodes/max/plantarium/branch/src/lib.rs
@@ -0,0 +1,116 @@
+use std::f32::consts::PI;
+
+use glam::Vec3;
+use macros::include_definition_file;
+use utils::{
+ concat_arg_vecs, evaluate_float, evaluate_int,
+ geometry::{create_path, get_direction_at_path, get_point_at_path, wrap_path, wrap_path_mut},
+ log, set_panic_hook, split_args,
+};
+use wasm_bindgen::prelude::*;
+
+include_definition_file!("src/input.json");
+
+#[wasm_bindgen]
+pub fn execute(input: &[i32]) -> Vec {
+ set_panic_hook();
+
+ let args = split_args(input);
+
+ let paths = split_args(args[0]);
+
+ let mut output: Vec> = Vec::new();
+
+ let resolution = evaluate_int(args[8]).max(4) as usize;
+ let depth = evaluate_int(args[6]);
+
+ let mut max_depth = 0;
+ for path_data in paths.iter() {
+ if path_data[2] != 0 {
+ continue;
+ }
+ max_depth = max_depth.max(path_data[3]);
+ }
+
+ for path_data in paths.iter() {
+ // if this is not a path don't modify it
+ if path_data[2] != 0 || path_data[3] < (max_depth - depth) {
+ output.push(path_data.to_vec());
+ continue;
+ }
+
+ let path = wrap_path(path_data);
+
+ let branch_amount = evaluate_int(args[7]).max(1);
+
+ let lowest_branch = evaluate_float(args[4]);
+ let highest_branch = evaluate_float(args[5]);
+
+ for i in 0..branch_amount {
+ let a = i as f32 / (branch_amount - 1).max(1) as f32;
+
+ let length = evaluate_float(args[1]);
+ let thickness = evaluate_float(args[2]);
+ let offset_single = evaluate_float(args[3]);
+
+ // log!("a: {}, length: {}, thickness: {}, offset_single: {}, lowest_branch: {}, highest_branch: {}", a, length, thickness, offset_single, lowest_branch, highest_branch);
+
+ // log!("a: {}, length: {}, thickness: {}, offset_single: {}, lowest_branch: {}, highest_branch: {}", a, length, thickness, offset_single, lowest_branch, highest_branch);
+ let root_alpha = (a * (highest_branch - lowest_branch) + lowest_branch)
+ .min(1.0)
+ .max(0.0);
+
+ let is_left = i % 2 == 0;
+
+ let branch_origin = get_point_at_path(path.points, root_alpha);
+ //const [_vx, , _vz] = interpolateSkeletonVec(stem.skeleton, a);
+ let direction_slice = get_direction_at_path(path.points, root_alpha);
+ let direction = Vec3::from_slice(&direction_slice).normalize();
+
+ let rotation_angle = if is_left { PI } else { -PI };
+
+ // check if diration contains NaN
+ if direction[0].is_nan() || direction[1].is_nan() || direction[2].is_nan() {
+ log!(
+ "BRANCH direction contains NaN: {:?}, slice: {:?} branch_origin: {:?}, branch: {}",
+ direction,
+ direction_slice,
+ branch_origin,
+ i
+ );
+ continue;
+ }
+
+ let branch_direction = Vec3::from_slice(&[
+ direction[0] * rotation_angle.cos() - direction[2] * rotation_angle.sin(),
+ 0.0,
+ direction[0] * rotation_angle.sin() + direction[2] * rotation_angle.cos(),
+ ])
+ .normalize();
+
+ log!(
+ "BRANCH depth: {}, branch_origin: {:?}, direction_at: {:?}, branch_direction: {:?}",
+ depth,
+ branch_origin,
+ direction,
+ branch_direction
+ );
+ let mut branch_data = create_path(resolution, depth + 1);
+ let branch = wrap_path_mut(&mut branch_data);
+
+ for j in 0..resolution {
+ let _a = j as f32 / (resolution - 1) as f32;
+ branch.points[j * 4] = branch_origin[0] + branch_direction[0] * _a * length;
+ branch.points[j * 4 + 1] = branch_origin[1] + branch_direction[1] * _a * length;
+ branch.points[j * 4 + 2] = branch_origin[2] + branch_direction[2] * _a * length;
+ branch.points[j * 4 + 3] = branch_origin[3] * thickness * (1.0 - _a);
+ }
+
+ output.push(branch_data);
+ }
+
+ output.push(path_data.to_vec());
+ }
+
+ concat_arg_vecs(output)
+}
diff --git a/nodes/max/plantarium/array/tests/web.rs b/nodes/max/plantarium/branch/tests/web.rs
similarity index 100%
rename from nodes/max/plantarium/array/tests/web.rs
rename to nodes/max/plantarium/branch/tests/web.rs
diff --git a/nodes/max/plantarium/branches/.gitignore b/nodes/max/plantarium/branches/.gitignore
deleted file mode 100644
index 4e30131..0000000
--- a/nodes/max/plantarium/branches/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-/target
-**/*.rs.bk
-Cargo.lock
-bin/
-pkg/
-wasm-pack.log
diff --git a/nodes/max/plantarium/branches/Cargo.toml b/nodes/max/plantarium/branches/Cargo.toml
deleted file mode 100644
index 9185f6a..0000000
--- a/nodes/max/plantarium/branches/Cargo.toml
+++ /dev/null
@@ -1,28 +0,0 @@
-[package]
-name = "template"
-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/branches/package.json b/nodes/max/plantarium/branches/package.json
deleted file mode 100644
index 86916c9..0000000
--- a/nodes/max/plantarium/branches/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "scripts": {
- "build": "wasm-pack build --release --out-name index --no-default-features",
- "dev": "cargo watch -s 'wasm-pack build --dev --out-name index --no-default-features'"
- }
-}
diff --git a/nodes/max/plantarium/branches/src/lib.rs b/nodes/max/plantarium/branches/src/lib.rs
deleted file mode 100644
index b2ac6b5..0000000
--- a/nodes/max/plantarium/branches/src/lib.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use macros::include_definition_file;
-use utils::{concat_args, decode_float, encode_float, get_args, set_panic_hook, wrap_arg};
-use wasm_bindgen::prelude::*;
-
-include_definition_file!("src/input.json");
-
-#[rustfmt::skip]
-#[wasm_bindgen]
-pub fn execute(input: &[i32]) -> Vec {
-
- set_panic_hook();
-
- let args = get_args(input);
-
- let paths = get_args(args[0]);
-
- concat_args(paths)
-}
diff --git a/nodes/max/plantarium/branches/tests/web.rs b/nodes/max/plantarium/branches/tests/web.rs
deleted file mode 100644
index de5c1da..0000000
--- a/nodes/max/plantarium/branches/tests/web.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//! 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/math/src/lib.rs b/nodes/max/plantarium/math/src/lib.rs
index 8b6c7bf..64cd584 100644
--- a/nodes/max/plantarium/math/src/lib.rs
+++ b/nodes/max/plantarium/math/src/lib.rs
@@ -1,5 +1,5 @@
use macros::include_definition_file;
-use utils::{concat_args, get_args, set_panic_hook};
+use utils::{concat_args, set_panic_hook, split_args};
use wasm_bindgen::prelude::*;
include_definition_file!("src/input.json");
@@ -7,6 +7,6 @@ include_definition_file!("src/input.json");
#[wasm_bindgen]
pub fn execute(args: &[i32]) -> Vec {
set_panic_hook();
- let args = get_args(args);
+ let args = split_args(args);
concat_args(vec![&[0], args[0], args[1], args[2]])
}
diff --git a/nodes/max/plantarium/noise/src/input.json b/nodes/max/plantarium/noise/src/input.json
index 31e1e41..66e740e 100644
--- a/nodes/max/plantarium/noise/src/input.json
+++ b/nodes/max/plantarium/noise/src/input.json
@@ -36,6 +36,13 @@
1,
1
]
+ },
+ "depth": {
+ "type": "integer",
+ "min": 1,
+ "max": 10,
+ "value": 1,
+ "hidden": true
}
}
}
diff --git a/nodes/max/plantarium/noise/src/lib.rs b/nodes/max/plantarium/noise/src/lib.rs
index c83fd22..a1f4933 100644
--- a/nodes/max/plantarium/noise/src/lib.rs
+++ b/nodes/max/plantarium/noise/src/lib.rs
@@ -2,8 +2,8 @@ use glam::Vec3;
use macros::include_definition_file;
use noise::{core::open_simplex::open_simplex_2d, permutationtable::PermutationTable, Vector2};
use utils::{
- concat_args, evaluate_float, evaluate_vec3, geometry::wrap_path, get_args, reset_call_count,
- set_panic_hook,
+ concat_args, evaluate_float, evaluate_int, evaluate_vec3, geometry::wrap_path_mut,
+ reset_call_count, set_panic_hook, split_args,
};
use wasm_bindgen::prelude::*;
@@ -19,9 +19,9 @@ pub fn execute(input: &[i32]) -> Vec {
reset_call_count();
- let args = get_args(input);
+ let args = split_args(input);
- let plants = get_args(args[0]);
+ let plants = split_args(args[0]);
let scale = (evaluate_float(args[1]) * 0.1) as f64;
let strength = evaluate_float(args[2]);
let fix_bottom = evaluate_float(args[3]);
@@ -30,8 +30,18 @@ pub fn execute(input: &[i32]) -> Vec {
let directional_strength = evaluate_vec3(args[5]);
+ let depth = evaluate_int(args[6]);
+
let hasher = PermutationTable::new(seed as u32);
+ let mut max_depth = 0;
+ for path_data in plants.iter() {
+ if path_data[2] != 0 {
+ continue;
+ }
+ max_depth = max_depth.max(path_data[3]);
+ }
+
let output: Vec> = plants
.iter()
.enumerate()
@@ -43,7 +53,11 @@ pub fn execute(input: &[i32]) -> Vec {
return path_data;
}
- let path = wrap_path(&mut path_data);
+ if path_data[3] < (max_depth - depth + 1) {
+ return path_data;
+ }
+
+ let path = wrap_path_mut(&mut path_data);
let p0 = Vec3::new(path.points[0], path.points[1], path.points[2]);
diff --git a/nodes/max/plantarium/output/src/lib.rs b/nodes/max/plantarium/output/src/lib.rs
index 4f4ccd3..6b674a4 100644
--- a/nodes/max/plantarium/output/src/lib.rs
+++ b/nodes/max/plantarium/output/src/lib.rs
@@ -2,7 +2,7 @@ use macros::include_definition_file;
use utils::{
concat_args, evaluate_int,
geometry::{extrude_path, wrap_path},
- get_args, log,
+ log, split_args,
};
use wasm_bindgen::prelude::*;
@@ -12,9 +12,11 @@ include_definition_file!("src/inputs.json");
pub fn execute(input: &[i32]) -> Vec {
utils::set_panic_hook();
- let args = get_args(input);
+ let args = split_args(input);
- let inputs = get_args(args[0]);
+ assert_eq!(args.len(), 2, "Expected 2 arguments, got {}", args.len());
+
+ let inputs = split_args(args[0]);
let resolution = evaluate_int(args[1]) as usize;
@@ -28,10 +30,9 @@ pub fn execute(input: &[i32]) -> Vec {
if arg_type == 0 {
// this is path
- let mut vec = arg.to_vec();
+ let vec = arg.to_vec();
output.push(vec.clone());
- let path_data = wrap_path(&mut vec);
- log!("{:?}", path_data);
+ let path_data = wrap_path(arg);
let geometry = extrude_path(path_data, resolution);
output.push(geometry);
} else if arg_type == 1 {
diff --git a/nodes/max/plantarium/random/src/lib.rs b/nodes/max/plantarium/random/src/lib.rs
index 3eef909..de8c164 100644
--- a/nodes/max/plantarium/random/src/lib.rs
+++ b/nodes/max/plantarium/random/src/lib.rs
@@ -1,5 +1,5 @@
use macros::include_definition_file;
-use utils::{concat_args, get_args, set_panic_hook};
+use utils::{concat_args, set_panic_hook, split_args};
use wasm_bindgen::prelude::*;
include_definition_file!("src/definition.json");
@@ -7,6 +7,6 @@ include_definition_file!("src/definition.json");
#[wasm_bindgen]
pub fn execute(args: &[i32]) -> Vec {
set_panic_hook();
- let args = get_args(args);
+ let args = split_args(args);
concat_args(vec![&[1], args[0], args[1], args[2]])
}
diff --git a/nodes/max/plantarium/stem/src/lib.rs b/nodes/max/plantarium/stem/src/lib.rs
index 7485671..c9a90a9 100644
--- a/nodes/max/plantarium/stem/src/lib.rs
+++ b/nodes/max/plantarium/stem/src/lib.rs
@@ -2,7 +2,7 @@ use macros::include_definition_file;
use utils::{
evaluate_float, evaluate_int, evaluate_vec3,
geometry::{create_multiple_paths, wrap_multiple_paths},
- get_args, log, reset_call_count, set_panic_hook,
+ log, reset_call_count, set_panic_hook, split_args,
};
use wasm_bindgen::prelude::*;
@@ -14,7 +14,7 @@ pub fn execute(input: &[i32]) -> Vec {
reset_call_count();
- let args = get_args(input);
+ let args = split_args(input);
let amount = evaluate_int(args[1]) as usize;
let path_resolution = evaluate_int(args[4]) as usize;
diff --git a/nodes/max/plantarium/sum/.gitignore b/nodes/max/plantarium/sum/.gitignore
deleted file mode 100644
index 4e30131..0000000
--- a/nodes/max/plantarium/sum/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-/target
-**/*.rs.bk
-Cargo.lock
-bin/
-pkg/
-wasm-pack.log
diff --git a/nodes/max/plantarium/sum/Cargo.toml b/nodes/max/plantarium/sum/Cargo.toml
deleted file mode 100644
index d344d8f..0000000
--- a/nodes/max/plantarium/sum/Cargo.toml
+++ /dev/null
@@ -1,28 +0,0 @@
-[package]
-name = "max-plantarium-sum"
-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" }
-serde = { version = "1.0", features = ["derive"] }
-serde-wasm-bindgen = "0.4"
-console_error_panic_hook = { version = "0.1.7", optional = true }
-macros = { version = "0.1.0", path = "../../../../packages/macros" }
-web-sys = { version = "0.3.69", features = ["console"] }
-
-[dev-dependencies]
-wasm-bindgen-test = "0.3.34"
diff --git a/nodes/max/plantarium/sum/package.json b/nodes/max/plantarium/sum/package.json
deleted file mode 100644
index 86916c9..0000000
--- a/nodes/max/plantarium/sum/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "scripts": {
- "build": "wasm-pack build --release --out-name index --no-default-features",
- "dev": "cargo watch -s 'wasm-pack build --dev --out-name index --no-default-features'"
- }
-}
diff --git a/nodes/max/plantarium/sum/src/input.json b/nodes/max/plantarium/sum/src/input.json
deleted file mode 100644
index c7d9367..0000000
--- a/nodes/max/plantarium/sum/src/input.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "id": "max/plantarium/sum",
- "outputs": [
- "float"
- ],
- "inputs": {
- "array": {
- "type": "float",
- "value": 2,
- "external": true
- }
- }
-}
diff --git a/nodes/max/plantarium/sum/src/lib.rs b/nodes/max/plantarium/sum/src/lib.rs
deleted file mode 100644
index 4cb3b79..0000000
--- a/nodes/max/plantarium/sum/src/lib.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use macros::include_definition_file;
-use utils::{decode_float, encode_float};
-use wasm_bindgen::prelude::*;
-
-include_definition_file!("src/input.json");
-
-#[wasm_bindgen]
-pub fn execute(input: &[i32]) -> Vec {
- utils::set_panic_hook();
-
- let mut sum = 0.0;
-
- // console::log_1(&format!("WASM(sum_node): args: {:?}", input).into());
-
- let length = (input.len() - 2) / 2;
-
- (0..length).for_each(|i| {
- // console::log_1(&format!("WASM(sum_node): i: {} sum: {:?}", i, sum).into());
- sum += decode_float(input[2 + i * 2]);
- });
-
- let encoded_sum = encode_float(sum);
-
- // console::log_1(&format!("WASM(sum_node): result: {:?}", sum).into());
-
- vec![0, 2, encoded_sum]
-}
diff --git a/nodes/max/plantarium/sum/tests/web.rs b/nodes/max/plantarium/sum/tests/web.rs
deleted file mode 100644
index de5c1da..0000000
--- a/nodes/max/plantarium/sum/tests/web.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//! 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/triangle/src/lib.rs b/nodes/max/plantarium/triangle/src/lib.rs
index 860771d..10040fe 100644
--- a/nodes/max/plantarium/triangle/src/lib.rs
+++ b/nodes/max/plantarium/triangle/src/lib.rs
@@ -1,5 +1,5 @@
use macros::include_definition_file;
-use utils::{decode_float, encode_float, evaluate_int, get_args, wrap_arg};
+use utils::{decode_float, encode_float, evaluate_int, split_args, wrap_arg};
use wasm_bindgen::prelude::*;
use web_sys::console;
@@ -11,7 +11,7 @@ pub fn execute(input: &[i32]) -> Vec {
utils::set_panic_hook();
- let args = get_args(input);
+ let args = split_args(input);
let size = evaluate_int(args[0]);
let decoded = decode_float(size);
diff --git a/nodes/max/plantarium/vec3/src/lib.rs b/nodes/max/plantarium/vec3/src/lib.rs
index 9531d5a..272156c 100644
--- a/nodes/max/plantarium/vec3/src/lib.rs
+++ b/nodes/max/plantarium/vec3/src/lib.rs
@@ -1,12 +1,12 @@
use macros::include_definition_file;
-use utils::{concat_args, get_args, log};
+use utils::{concat_args, log, split_args};
use wasm_bindgen::prelude::*;
include_definition_file!("src/input.json");
#[wasm_bindgen]
pub fn execute(input: &[i32]) -> Vec {
- let args = get_args(input);
+ let args = split_args(input);
log!("vec3 input: {:?}", input);
log!("vec3 args: {:?}", args);
concat_args(args)
diff --git a/packages/utils/src/geometry/geometry_data.rs b/packages/utils/src/geometry/geometry_data.rs
index b2a8cfd..3e0f4d5 100644
--- a/packages/utils/src/geometry/geometry_data.rs
+++ b/packages/utils/src/geometry/geometry_data.rs
@@ -1,16 +1,16 @@
use crate::log;
+static GEOMETRY_HEADER_SIZE: usize = 3;
+// 0: geometry type = 0
+// 1: vertex amount
+// 2: face amount
+
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`
}
-static GEOMETRY_HEADER_SIZE: usize = 3;
-// 0: geometry type = 0
-// 1: vertex amount
-// 2: face amount
-
pub fn create_geometry_data(vertex_amount: usize, face_amount: usize) -> Vec {
let amount = GEOMETRY_HEADER_SIZE // definition (type, vertex_amount, face_amount)
+ 4 // opening and closing brackets
diff --git a/packages/utils/src/geometry/path_data.rs b/packages/utils/src/geometry/path_data.rs
index 5b6df35..c13e085 100644
--- a/packages/utils/src/geometry/path_data.rs
+++ b/packages/utils/src/geometry/path_data.rs
@@ -1,14 +1,20 @@
-static PATH_HEADER_SIZE: usize = 2;
// 0: node-type, stem: 0
// 1: depth
+static PATH_HEADER_SIZE: usize = 2;
#[derive(Debug)]
-pub struct PathData<'a> {
- pub header: &'a mut [i32],
+pub struct PathDataMut<'a> {
pub length: usize,
+ pub depth: i32,
pub points: &'a mut [f32],
}
+pub struct PathData<'a> {
+ pub depth: i32,
+ pub length: usize,
+ pub points: &'a [f32],
+}
+
pub fn create_multiple_paths(amount: usize, point_amount: usize, depth: i32) -> Vec {
let output_size = amount * (point_amount * 4 + PATH_HEADER_SIZE + 4) + 4;
@@ -35,7 +41,7 @@ pub fn create_multiple_paths(amount: usize, point_amount: usize, depth: i32) ->
path
}
-pub fn wrap_multiple_paths(mut input: &mut [i32]) -> Vec> {
+pub fn wrap_multiple_paths(mut input: &mut [i32]) -> Vec> {
let mut paths = Vec::new();
let mut end_index = 2;
@@ -46,7 +52,7 @@ pub fn wrap_multiple_paths(mut input: &mut [i32]) -> Vec> {
end_index = input[1] as usize + 3;
if end_index < input.len() {
let (path_slice, remaining) = input.split_at_mut(end_index);
- let path_data = wrap_path(path_slice);
+ let path_data = wrap_path_mut(path_slice);
paths.push(path_data);
input = remaining;
} else {
@@ -63,7 +69,7 @@ pub fn create_path(point_amount: usize, depth: i32) -> Vec {
let mut path: Vec = vec![0; output_size];
path[0] = 0; // encode opening bracket
- path[1] = (point_amount * 4) as i32 + 2; // encode opening bracket
+ path[1] = ((point_amount * 4) + PATH_HEADER_SIZE + 1) as i32; // encode opening bracket
path[2] = 0; //encode node-type, stem: 0
path[3] = depth; //encode depth
path[output_size - 2] = 1; // encode closing bracket
@@ -72,7 +78,39 @@ pub fn create_path(point_amount: usize, depth: i32) -> Vec {
path
}
-pub fn wrap_path<'a>(geometry: &'a mut [i32]) -> PathData<'a> {
+pub fn wrap_path(input: &[i32]) -> PathData {
+ // Basic validity checks
+ assert!(
+ input.len() > PATH_HEADER_SIZE,
+ "Geometry vector does not contain enough data for a header."
+ );
+
+ let rest = &input[2..];
+
+ let header = &rest[..PATH_HEADER_SIZE];
+
+ let points_slice = &rest[PATH_HEADER_SIZE..rest.len() - 2];
+
+ assert!(
+ points_slice.len() % 4 == 0,
+ "Points slice does not match the expected size. {}",
+ points_slice.len()
+ );
+
+ let length = points_slice.len() / 4;
+
+ let points: &[f32] = unsafe {
+ std::slice::from_raw_parts(points_slice.as_ptr() as *const f32, points_slice.len())
+ };
+
+ PathData {
+ depth: header[1],
+ length,
+ points,
+ }
+}
+
+pub fn wrap_path_mut<'a>(geometry: &'a mut [i32]) -> PathDataMut<'a> {
// Basic validity checks
assert!(
geometry.len() > PATH_HEADER_SIZE,
@@ -89,7 +127,8 @@ pub fn wrap_path<'a>(geometry: &'a mut [i32]) -> PathData<'a> {
assert!(
points_slice.len() % 4 == 0,
- "Points slice does not match the expected size.",
+ "Points slice does not match the expected size. {}",
+ points_slice.len()
);
let length = points_slice.len() / 4;
@@ -98,9 +137,73 @@ pub fn wrap_path<'a>(geometry: &'a mut [i32]) -> PathData<'a> {
std::slice::from_raw_parts_mut(points_slice.as_mut_ptr() as *mut f32, points_slice.len())
};
- PathData {
- header,
+ PathDataMut {
+ depth: header[1],
length,
points,
}
}
+
+pub fn get_point_at_path(path: &[f32], alpha: f32) -> [f32; 4] {
+ let a = alpha.min(0.999999).max(0.000001);
+
+ let num_points = path.len() / 4;
+ let segment_length = 1.0 / (num_points - 1) as f32;
+ let mut target_index = (a / segment_length).floor() as usize;
+ target_index = target_index.min(num_points - 2); // Ensure it doesn't exceed bounds
+
+ let start_index = target_index * 4;
+ let end_index = (target_index + 1) * 4;
+
+ let t = (a - target_index as f32 * segment_length) / segment_length;
+
+ let x1 = path[start_index];
+ let y1 = path[start_index + 1];
+ let z1 = path[start_index + 2];
+ let w1 = path[start_index + 3];
+
+ let x2 = path[end_index];
+ let y2 = path[end_index + 1];
+ let z2 = path[end_index + 2];
+ let w2 = path[end_index + 3];
+
+ // Linear interpolation
+ let x = x1 + t * (x2 - x1);
+ let y = y1 + t * (y2 - y1);
+ let z = z1 + t * (z2 - z1);
+ let w = w1 + t * (w2 - w1);
+
+ [x, y, z, w]
+}
+
+pub fn get_direction_at_path(path: &[f32], alpha: f32) -> [f32; 3] {
+ let num_points = path.len() / 4;
+
+ let a = alpha.min(0.999999).max(0.000001);
+
+ let segment_length = 1.0 / (num_points - 1) as f32;
+ let target_index = (a / segment_length).floor() as usize;
+
+ let start_index = target_index * 4;
+ let end_index = (target_index + 1) * 4;
+
+ let x1 = path[start_index];
+ let y1 = path[start_index + 1];
+ let z1 = path[start_index + 2];
+ let x2 = path[end_index];
+ let y2 = path[end_index + 1];
+ let z2 = path[end_index + 2];
+
+ // Direction vector (not normalized)
+ let dx = x2 - x1;
+ let dy = y2 - y1;
+ let dz = z2 - z1;
+
+ let norm = (dx * dx + dy * dy + dz * dz).sqrt();
+
+ if norm == 0.0 {
+ return [0.0, 1.0, 0.0];
+ }
+
+ [dx / norm, dy / norm, dz / norm]
+}
diff --git a/packages/utils/src/tree.rs b/packages/utils/src/tree.rs
index 89e27dc..ef7854d 100644
--- a/packages/utils/src/tree.rs
+++ b/packages/utils/src/tree.rs
@@ -1,6 +1,6 @@
use crate::decode_float;
-pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
+pub fn split_args(args: &[i32]) -> Vec<&[i32]> {
println!("-------------------");
println!("{:?}", args);
@@ -47,14 +47,12 @@ pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
}
i += 2;
continue;
+ } else if depth == 1 {
+ out_args.push(&args[i..i + 1]);
+ println!("-> {:?}", &args[i..i + 1]);
+ start_index = i + 1;
} else {
- if depth == 1 {
- out_args.push(&args[i..i + 1]);
- println!("-> {:?}", &args[i..i + 1]);
- start_index = i + 1;
- } else {
- println!("{}", val);
- }
+ println!("{}", val);
}
i += 1;
@@ -63,6 +61,46 @@ pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
out_args
}
+pub fn concat_arg_vecs(data: Vec>) -> Vec {
+ let mut total_length = 4; // Start with 4 to account for [0, 1] at the start and [1, 1] at the end
+
+ // Calculate the total length first to avoid reallocations
+ for vec in &data {
+ if vec.len() == 1 {
+ total_length += 1;
+ } else {
+ total_length += vec.len(); // +4 for [0, 1] and [1, 1] per inner vec
+ }
+ }
+
+ let mut result = Vec::with_capacity(total_length);
+
+ // Add [0, 1] initially
+ result.push(0);
+ result.push(1);
+
+ let mut last_closing_bracket = 1;
+
+ // Process each vector
+ for vec in data {
+ if vec.len() == 1 {
+ result.push(vec[0]);
+ result[last_closing_bracket] += 1;
+ continue;
+ } else {
+ result.extend(vec);
+ last_closing_bracket = result.len() - 1;
+ result[last_closing_bracket] = 1;
+ }
+ }
+
+ // Add [1, 1] at the end
+ result.push(1);
+ result.push(1);
+
+ result
+}
+
pub fn concat_args(mut data: Vec<&[i32]>) -> Vec {
let mut total_length = 4; // Start with 4 to account for [0, 1] at the start and [1, 1] at the end
@@ -131,7 +169,7 @@ pub fn evaluate_vec3(input_args: &[i32]) -> Vec {
];
}
- let args = get_args(input_args);
+ let args = split_args(input_args);
assert!(
args.len() == 3,
@@ -156,7 +194,7 @@ pub fn evaluate_int(input_args: &[i32]) -> i32 {
return input_args[0];
}
- let args = get_args(input_args);
+ let args = split_args(input_args);
let mut resolved: Vec = Vec::new();
@@ -192,7 +230,7 @@ mod tests {
1053609165, 54,
];
- let args = get_args(&input);
+ let args = split_args(&input);
println!("{:?}", args[0]);
assert_eq!(args[0].len(), 29);
@@ -219,7 +257,7 @@ mod tests {
let input_a = vec![0, 4, 1, 2, 3, 0, 7, 1, 2, 4, 2, 4, 1, 1, 1, 1];
// -> [1, 2, 3, [1, 2, 4, 2, 4]]
- let args = get_args(&input_a);
+ let args = split_args(&input_a);
println!("{:?}", args);
@@ -235,7 +273,7 @@ mod tests {
let input_b = vec![0, 3, 7, 1, 0, 4, 4, 2, 4, 1, 2, 2, 0, 3, 2, 3, 1, 1, 1, 1];
// -> [1,[4,2,4], 2, [2,3]]
- let args = get_args(&input_b);
+ let args = split_args(&input_b);
assert_eq!(args.len(), 5);
assert_eq!(args[0], [7]);
@@ -258,14 +296,14 @@ mod tests {
// 2 -> first number
// 3 -> second number
- let args = get_args(&input);
+ let args = split_args(&input);
assert_eq!(args.len(), 4);
assert_eq!(args[0], [0]);
assert_eq!(args[1], [2]);
assert_eq!(args[3], [0, 3, 0, 128]);
- let nested_args = get_args(args[2]);
+ let nested_args = split_args(args[2]);
assert_eq!(nested_args.len(), 4);
}