feat: implement branch node (almost finsihed)
This commit is contained in:
parent
4db1cc7d4f
commit
2de2560a57
45
Cargo.lock
generated
45
Cargo.lock
generated
@ -3,7 +3,13 @@
|
|||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[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"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
@ -17,16 +23,11 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "branch"
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "box"
|
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
|
"glam",
|
||||||
"macros",
|
"macros",
|
||||||
"serde",
|
"serde",
|
||||||
"serde-wasm-bindgen",
|
"serde-wasm-bindgen",
|
||||||
@ -123,20 +124,6 @@ dependencies = [
|
|||||||
"web-sys",
|
"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]]
|
[[package]]
|
||||||
name = "max-plantarium-triangle"
|
name = "max-plantarium-triangle"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -367,20 +354,6 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"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]]
|
[[package]]
|
||||||
name = "types"
|
name = "types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
useTexture,
|
useTexture,
|
||||||
} from "@threlte/extras";
|
} from "@threlte/extras";
|
||||||
import {
|
import {
|
||||||
Texture,
|
|
||||||
type BufferGeometry,
|
type BufferGeometry,
|
||||||
type PerspectiveCamera,
|
type PerspectiveCamera,
|
||||||
type Vector3,
|
type Vector3,
|
||||||
@ -16,7 +15,6 @@
|
|||||||
import { OrbitControls } from "@threlte/extras";
|
import { OrbitControls } from "@threlte/extras";
|
||||||
import { AppSettings } from "../settings/app-settings";
|
import { AppSettings } from "../settings/app-settings";
|
||||||
import localStore from "$lib/helpers/localStore";
|
import localStore from "$lib/helpers/localStore";
|
||||||
import { Inspector } from "three-inspect";
|
|
||||||
|
|
||||||
export let geometries: BufferGeometry[];
|
export let geometries: BufferGeometry[];
|
||||||
export let lines: Vector3[][];
|
export let lines: Vector3[][];
|
||||||
@ -89,13 +87,9 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#await matcap then value}
|
{#await matcap then value}
|
||||||
<T.Mesh geometry={geo}>
|
<T.Mesh geometry={geo}>
|
||||||
<T.MeshMatcapMaterial matcap={value} />
|
<T.MeshMatcapMaterial matcap={value} wireframe={$AppSettings.wireframe} />
|
||||||
{#if false}
|
{#if false}
|
||||||
<T.MeshStandardMaterial
|
<T.MeshStandardMaterial color="green" depthTest={true} />
|
||||||
color="green"
|
|
||||||
depthTest={true}
|
|
||||||
wireframe={$AppSettings.wireframe}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
</T.Mesh>
|
</T.Mesh>
|
||||||
{/await}
|
{/await}
|
||||||
|
@ -64,11 +64,17 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if node}
|
{#if node}
|
||||||
|
{#key node.id}
|
||||||
{#if nodeDefinition && store && Object.keys(nodeDefinition).length > 0}
|
{#if nodeDefinition && store && Object.keys(nodeDefinition).length > 0}
|
||||||
<NestedSettings id="activeNodeSettings" settings={nodeDefinition} {store} />
|
<NestedSettings
|
||||||
|
id="activeNodeSettings"
|
||||||
|
settings={nodeDefinition}
|
||||||
|
{store}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="mx-4">Active Node has no Settings</p>
|
<p class="mx-4">Active Node has no Settings</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
{/key}
|
||||||
{:else}
|
{:else}
|
||||||
<p class="mx-4">No active node</p>
|
<p class="mx-4">No active node</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -49,10 +49,25 @@
|
|||||||
let keymap: ReturnType<typeof createKeyMap>;
|
let keymap: ReturnType<typeof createKeyMap>;
|
||||||
|
|
||||||
function handleResult(event: CustomEvent<Graph>) {
|
function handleResult(event: CustomEvent<Graph>) {
|
||||||
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) {
|
if ($AppSettings.centerCamera && viewerCamera && 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.target.copy(viewerCenter);
|
||||||
|
}
|
||||||
viewerControls.update();
|
viewerControls.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,7 +76,7 @@
|
|||||||
localStorage.setItem("graph", JSON.stringify(event.detail));
|
localStorage.setItem("graph", JSON.stringify(event.detail));
|
||||||
}
|
}
|
||||||
|
|
||||||
let settings: Record<string, any> = {
|
let settingPanels: Record<string, any> = {
|
||||||
general: {
|
general: {
|
||||||
id: "general",
|
id: "general",
|
||||||
icon: "i-tabler-settings",
|
icon: "i-tabler-settings",
|
||||||
@ -90,33 +105,33 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
$: if (keymap) {
|
$: if (keymap) {
|
||||||
settings.shortcuts = {
|
settingPanels.shortcuts = {
|
||||||
id: "shortcuts",
|
id: "shortcuts",
|
||||||
icon: "i-tabler-keyboard",
|
icon: "i-tabler-keyboard",
|
||||||
props: { keymap },
|
props: { keymap },
|
||||||
component: Keymap,
|
component: Keymap,
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = settings;
|
settingPanels = settingPanels;
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (manager) {
|
$: if (manager) {
|
||||||
settings.activeNode.props.manager = manager;
|
settingPanels.activeNode.props.manager = manager;
|
||||||
settings.nodeStore = {
|
settingPanels.nodeStore = {
|
||||||
id: "Node Store",
|
id: "Node Store",
|
||||||
icon: "i-tabler-database",
|
icon: "i-tabler-database",
|
||||||
props: { nodeRegistry, manager },
|
props: { nodeRegistry, manager },
|
||||||
component: NodeStore,
|
component: NodeStore,
|
||||||
};
|
};
|
||||||
settings = settings;
|
settingPanels = settingPanels;
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (activeNode) {
|
$: if (activeNode) {
|
||||||
settings.activeNode.props.node = activeNode;
|
settingPanels.activeNode.props.node = activeNode;
|
||||||
settings = settings;
|
settingPanels = settingPanels;
|
||||||
} else {
|
} else {
|
||||||
settings.activeNode.props.node = undefined;
|
settingPanels.activeNode.props.node = undefined;
|
||||||
settings = settings;
|
settingPanels = settingPanels;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSettings(
|
function handleSettings(
|
||||||
@ -125,25 +140,25 @@
|
|||||||
types: Record<string, unknown>;
|
types: Record<string, unknown>;
|
||||||
}>,
|
}>,
|
||||||
) {
|
) {
|
||||||
settings.general.definition.debug.stressTest.loadGrid.callback =
|
settingPanels.general.definition.debug.stressTest.loadGrid.callback =
|
||||||
function () {
|
function () {
|
||||||
const store = get(settings.general.settings);
|
const store = get(settingPanels.general.settings);
|
||||||
graph = templates.grid(store.amount, store.amount);
|
graph = templates.grid(store.amount, store.amount);
|
||||||
};
|
};
|
||||||
|
|
||||||
settings.general.definition.debug.stressTest.loadTree.callback =
|
settingPanels.general.definition.debug.stressTest.loadTree.callback =
|
||||||
function () {
|
function () {
|
||||||
const store = get(settings.general.settings);
|
const store = get(settingPanels.general.settings);
|
||||||
graph = templates.tree(store.amount);
|
graph = templates.tree(store.amount);
|
||||||
};
|
};
|
||||||
|
|
||||||
settings.graph.settings = writable(ev.detail.values);
|
settingPanels.graph.settings = writable(ev.detail.values);
|
||||||
settings.graph.definition = {
|
settingPanels.graph.definition = {
|
||||||
...settings.graph.definition,
|
...settingPanels.graph.definition,
|
||||||
...ev.detail.types,
|
...ev.detail.types,
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = settings;
|
settingPanels = settingPanels;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -168,12 +183,12 @@
|
|||||||
bind:keymap
|
bind:keymap
|
||||||
showGrid={$AppSettings?.showNodeGrid}
|
showGrid={$AppSettings?.showNodeGrid}
|
||||||
snapToGrid={$AppSettings?.snapToGrid}
|
snapToGrid={$AppSettings?.snapToGrid}
|
||||||
settings={settings?.graph?.settings}
|
settings={settingPanels?.graph?.settings}
|
||||||
on:settings={handleSettings}
|
on:settings={handleSettings}
|
||||||
on:result={handleResult}
|
on:result={handleResult}
|
||||||
on:save={handleSave}
|
on:save={handleSave}
|
||||||
/>
|
/>
|
||||||
<Settings panels={settings}></Settings>
|
<Settings panels={settingPanels}></Settings>
|
||||||
{/key}
|
{/key}
|
||||||
</Grid.Cell>
|
</Grid.Cell>
|
||||||
</Grid.Row>
|
</Grid.Row>
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "max/plantarium/array",
|
|
||||||
"outputs": [
|
|
||||||
"float"
|
|
||||||
],
|
|
||||||
"inputs": {
|
|
||||||
"value": {
|
|
||||||
"type": "float",
|
|
||||||
"value": 4.2
|
|
||||||
},
|
|
||||||
"amount": {
|
|
||||||
"type": "integer",
|
|
||||||
"value": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<i32> {
|
|
||||||
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<i32> = 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
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
use macros::include_definition_file;
|
use macros::include_definition_file;
|
||||||
use utils::{
|
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 wasm_bindgen::prelude::*;
|
||||||
use web_sys::console;
|
use web_sys::console;
|
||||||
@ -13,7 +13,7 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
|
|
||||||
set_panic_hook();
|
set_panic_hook();
|
||||||
|
|
||||||
let args = get_args(input);
|
let args = split_args(input);
|
||||||
|
|
||||||
console::log_1(&format!("WASM(cube): input: {:?} -> {:?}", input, args ).into());
|
console::log_1(&format!("WASM(cube): input: {:?} -> {:?}", input, args ).into());
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "array"
|
name = "branch"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Max Richter <jim-x@web.de>"]
|
authors = ["Max Richter <jim-x@web.de>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
@ -19,10 +19,11 @@ wasm-bindgen = "0.2.84"
|
|||||||
# code size when deploying.
|
# code size when deploying.
|
||||||
utils = { version = "0.1.0", path = "../../../../packages/utils" }
|
utils = { version = "0.1.0", path = "../../../../packages/utils" }
|
||||||
macros = { version = "0.1.0", path = "../../../../packages/macros" }
|
macros = { version = "0.1.0", path = "../../../../packages/macros" }
|
||||||
web-sys = { version = "0.3.69", features = ["console"] }
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde-wasm-bindgen = "0.4"
|
serde-wasm-bindgen = "0.4"
|
||||||
console_error_panic_hook = { version = "0.1.7", optional = true }
|
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||||
|
web-sys = { version = "0.3.69", features = ["console"] }
|
||||||
|
glam = "0.27.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wasm-bindgen-test = "0.3.34"
|
wasm-bindgen-test = "0.3.34"
|
@ -15,7 +15,7 @@
|
|||||||
"step": 0.05,
|
"step": 0.05,
|
||||||
"value": 0.8
|
"value": 0.8
|
||||||
},
|
},
|
||||||
"thiccness": {
|
"thickness": {
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"min": 0,
|
"min": 0,
|
||||||
"max": 1,
|
"max": 1,
|
||||||
@ -47,7 +47,7 @@
|
|||||||
"value": 1
|
"value": 1
|
||||||
},
|
},
|
||||||
"depth": {
|
"depth": {
|
||||||
"type": "float",
|
"type": "integer",
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"min": 1,
|
"min": 1,
|
||||||
"value": 1,
|
"value": 1,
|
116
nodes/max/plantarium/branch/src/lib.rs
Normal file
116
nodes/max/plantarium/branch/src/lib.rs
Normal file
@ -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<i32> {
|
||||||
|
set_panic_hook();
|
||||||
|
|
||||||
|
let args = split_args(input);
|
||||||
|
|
||||||
|
let paths = split_args(args[0]);
|
||||||
|
|
||||||
|
let mut output: Vec<Vec<i32>> = 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)
|
||||||
|
}
|
6
nodes/max/plantarium/branches/.gitignore
vendored
6
nodes/max/plantarium/branches/.gitignore
vendored
@ -1,6 +0,0 @@
|
|||||||
/target
|
|
||||||
**/*.rs.bk
|
|
||||||
Cargo.lock
|
|
||||||
bin/
|
|
||||||
pkg/
|
|
||||||
wasm-pack.log
|
|
@ -1,28 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "template"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Max Richter <jim-x@web.de>"]
|
|
||||||
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"
|
|
@ -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'"
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<i32> {
|
|
||||||
|
|
||||||
set_panic_hook();
|
|
||||||
|
|
||||||
let args = get_args(input);
|
|
||||||
|
|
||||||
let paths = get_args(args[0]);
|
|
||||||
|
|
||||||
concat_args(paths)
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
use macros::include_definition_file;
|
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::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
include_definition_file!("src/input.json");
|
include_definition_file!("src/input.json");
|
||||||
@ -7,6 +7,6 @@ include_definition_file!("src/input.json");
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn execute(args: &[i32]) -> Vec<i32> {
|
pub fn execute(args: &[i32]) -> Vec<i32> {
|
||||||
set_panic_hook();
|
set_panic_hook();
|
||||||
let args = get_args(args);
|
let args = split_args(args);
|
||||||
concat_args(vec![&[0], args[0], args[1], args[2]])
|
concat_args(vec![&[0], args[0], args[1], args[2]])
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,13 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"depth": {
|
||||||
|
"type": "integer",
|
||||||
|
"min": 1,
|
||||||
|
"max": 10,
|
||||||
|
"value": 1,
|
||||||
|
"hidden": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ use glam::Vec3;
|
|||||||
use macros::include_definition_file;
|
use macros::include_definition_file;
|
||||||
use noise::{core::open_simplex::open_simplex_2d, permutationtable::PermutationTable, Vector2};
|
use noise::{core::open_simplex::open_simplex_2d, permutationtable::PermutationTable, Vector2};
|
||||||
use utils::{
|
use utils::{
|
||||||
concat_args, evaluate_float, evaluate_vec3, geometry::wrap_path, get_args, reset_call_count,
|
concat_args, evaluate_float, evaluate_int, evaluate_vec3, geometry::wrap_path_mut,
|
||||||
set_panic_hook,
|
reset_call_count, set_panic_hook, split_args,
|
||||||
};
|
};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@ -19,9 +19,9 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
|
|
||||||
reset_call_count();
|
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 scale = (evaluate_float(args[1]) * 0.1) as f64;
|
||||||
let strength = evaluate_float(args[2]);
|
let strength = evaluate_float(args[2]);
|
||||||
let fix_bottom = evaluate_float(args[3]);
|
let fix_bottom = evaluate_float(args[3]);
|
||||||
@ -30,8 +30,18 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
|
|
||||||
let directional_strength = evaluate_vec3(args[5]);
|
let directional_strength = evaluate_vec3(args[5]);
|
||||||
|
|
||||||
|
let depth = evaluate_int(args[6]);
|
||||||
|
|
||||||
let hasher = PermutationTable::new(seed as u32);
|
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<Vec<i32>> = plants
|
let output: Vec<Vec<i32>> = plants
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@ -43,7 +53,11 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
return path_data;
|
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]);
|
let p0 = Vec3::new(path.points[0], path.points[1], path.points[2]);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use macros::include_definition_file;
|
|||||||
use utils::{
|
use utils::{
|
||||||
concat_args, evaluate_int,
|
concat_args, evaluate_int,
|
||||||
geometry::{extrude_path, wrap_path},
|
geometry::{extrude_path, wrap_path},
|
||||||
get_args, log,
|
log, split_args,
|
||||||
};
|
};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@ -12,9 +12,11 @@ include_definition_file!("src/inputs.json");
|
|||||||
pub fn execute(input: &[i32]) -> Vec<i32> {
|
pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||||
utils::set_panic_hook();
|
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;
|
let resolution = evaluate_int(args[1]) as usize;
|
||||||
|
|
||||||
@ -28,10 +30,9 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
|
|
||||||
if arg_type == 0 {
|
if arg_type == 0 {
|
||||||
// this is path
|
// this is path
|
||||||
let mut vec = arg.to_vec();
|
let vec = arg.to_vec();
|
||||||
output.push(vec.clone());
|
output.push(vec.clone());
|
||||||
let path_data = wrap_path(&mut vec);
|
let path_data = wrap_path(arg);
|
||||||
log!("{:?}", path_data);
|
|
||||||
let geometry = extrude_path(path_data, resolution);
|
let geometry = extrude_path(path_data, resolution);
|
||||||
output.push(geometry);
|
output.push(geometry);
|
||||||
} else if arg_type == 1 {
|
} else if arg_type == 1 {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use macros::include_definition_file;
|
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::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
include_definition_file!("src/definition.json");
|
include_definition_file!("src/definition.json");
|
||||||
@ -7,6 +7,6 @@ include_definition_file!("src/definition.json");
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn execute(args: &[i32]) -> Vec<i32> {
|
pub fn execute(args: &[i32]) -> Vec<i32> {
|
||||||
set_panic_hook();
|
set_panic_hook();
|
||||||
let args = get_args(args);
|
let args = split_args(args);
|
||||||
concat_args(vec![&[1], args[0], args[1], args[2]])
|
concat_args(vec![&[1], args[0], args[1], args[2]])
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use macros::include_definition_file;
|
|||||||
use utils::{
|
use utils::{
|
||||||
evaluate_float, evaluate_int, evaluate_vec3,
|
evaluate_float, evaluate_int, evaluate_vec3,
|
||||||
geometry::{create_multiple_paths, wrap_multiple_paths},
|
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::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
|
|
||||||
reset_call_count();
|
reset_call_count();
|
||||||
|
|
||||||
let args = get_args(input);
|
let args = split_args(input);
|
||||||
|
|
||||||
let amount = evaluate_int(args[1]) as usize;
|
let amount = evaluate_int(args[1]) as usize;
|
||||||
let path_resolution = evaluate_int(args[4]) as usize;
|
let path_resolution = evaluate_int(args[4]) as usize;
|
||||||
|
6
nodes/max/plantarium/sum/.gitignore
vendored
6
nodes/max/plantarium/sum/.gitignore
vendored
@ -1,6 +0,0 @@
|
|||||||
/target
|
|
||||||
**/*.rs.bk
|
|
||||||
Cargo.lock
|
|
||||||
bin/
|
|
||||||
pkg/
|
|
||||||
wasm-pack.log
|
|
@ -1,28 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "max-plantarium-sum"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Max Richter <jim-x@web.de>"]
|
|
||||||
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"
|
|
@ -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'"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "max/plantarium/sum",
|
|
||||||
"outputs": [
|
|
||||||
"float"
|
|
||||||
],
|
|
||||||
"inputs": {
|
|
||||||
"array": {
|
|
||||||
"type": "float",
|
|
||||||
"value": 2,
|
|
||||||
"external": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<i32> {
|
|
||||||
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]
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
use macros::include_definition_file;
|
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 wasm_bindgen::prelude::*;
|
||||||
use web_sys::console;
|
use web_sys::console;
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
|
|
||||||
utils::set_panic_hook();
|
utils::set_panic_hook();
|
||||||
|
|
||||||
let args = get_args(input);
|
let args = split_args(input);
|
||||||
|
|
||||||
let size = evaluate_int(args[0]);
|
let size = evaluate_int(args[0]);
|
||||||
let decoded = decode_float(size);
|
let decoded = decode_float(size);
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use macros::include_definition_file;
|
use macros::include_definition_file;
|
||||||
use utils::{concat_args, get_args, log};
|
use utils::{concat_args, log, split_args};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
include_definition_file!("src/input.json");
|
include_definition_file!("src/input.json");
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn execute(input: &[i32]) -> Vec<i32> {
|
pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||||
let args = get_args(input);
|
let args = split_args(input);
|
||||||
log!("vec3 input: {:?}", input);
|
log!("vec3 input: {:?}", input);
|
||||||
log!("vec3 args: {:?}", args);
|
log!("vec3 args: {:?}", args);
|
||||||
concat_args(args)
|
concat_args(args)
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
use crate::log;
|
use crate::log;
|
||||||
|
|
||||||
|
static GEOMETRY_HEADER_SIZE: usize = 3;
|
||||||
|
// 0: geometry type = 0
|
||||||
|
// 1: vertex amount
|
||||||
|
// 2: face amount
|
||||||
|
|
||||||
pub struct GeometryData<'a> {
|
pub struct GeometryData<'a> {
|
||||||
pub positions: &'a mut [f32], // View into `data`
|
pub positions: &'a mut [f32], // View into `data`
|
||||||
pub normals: &'a mut [f32], // View into `data`
|
pub normals: &'a mut [f32], // View into `data`
|
||||||
pub faces: &'a mut [i32], // 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<i32> {
|
pub fn create_geometry_data(vertex_amount: usize, face_amount: usize) -> Vec<i32> {
|
||||||
let amount = GEOMETRY_HEADER_SIZE // definition (type, vertex_amount, face_amount)
|
let amount = GEOMETRY_HEADER_SIZE // definition (type, vertex_amount, face_amount)
|
||||||
+ 4 // opening and closing brackets
|
+ 4 // opening and closing brackets
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
static PATH_HEADER_SIZE: usize = 2;
|
|
||||||
// 0: node-type, stem: 0
|
// 0: node-type, stem: 0
|
||||||
// 1: depth
|
// 1: depth
|
||||||
|
static PATH_HEADER_SIZE: usize = 2;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PathData<'a> {
|
pub struct PathDataMut<'a> {
|
||||||
pub header: &'a mut [i32],
|
|
||||||
pub length: usize,
|
pub length: usize,
|
||||||
|
pub depth: i32,
|
||||||
pub points: &'a mut [f32],
|
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<i32> {
|
pub fn create_multiple_paths(amount: usize, point_amount: usize, depth: i32) -> Vec<i32> {
|
||||||
let output_size = amount * (point_amount * 4 + PATH_HEADER_SIZE + 4) + 4;
|
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
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wrap_multiple_paths(mut input: &mut [i32]) -> Vec<PathData<'_>> {
|
pub fn wrap_multiple_paths(mut input: &mut [i32]) -> Vec<PathDataMut<'_>> {
|
||||||
let mut paths = Vec::new();
|
let mut paths = Vec::new();
|
||||||
let mut end_index = 2;
|
let mut end_index = 2;
|
||||||
|
|
||||||
@ -46,7 +52,7 @@ pub fn wrap_multiple_paths(mut input: &mut [i32]) -> Vec<PathData<'_>> {
|
|||||||
end_index = input[1] as usize + 3;
|
end_index = input[1] as usize + 3;
|
||||||
if end_index < input.len() {
|
if end_index < input.len() {
|
||||||
let (path_slice, remaining) = input.split_at_mut(end_index);
|
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);
|
paths.push(path_data);
|
||||||
input = remaining;
|
input = remaining;
|
||||||
} else {
|
} else {
|
||||||
@ -63,7 +69,7 @@ pub fn create_path(point_amount: usize, depth: i32) -> Vec<i32> {
|
|||||||
let mut path: Vec<i32> = vec![0; output_size];
|
let mut path: Vec<i32> = vec![0; output_size];
|
||||||
|
|
||||||
path[0] = 0; // encode opening bracket
|
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[2] = 0; //encode node-type, stem: 0
|
||||||
path[3] = depth; //encode depth
|
path[3] = depth; //encode depth
|
||||||
path[output_size - 2] = 1; // encode closing bracket
|
path[output_size - 2] = 1; // encode closing bracket
|
||||||
@ -72,7 +78,39 @@ pub fn create_path(point_amount: usize, depth: i32) -> Vec<i32> {
|
|||||||
path
|
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
|
// Basic validity checks
|
||||||
assert!(
|
assert!(
|
||||||
geometry.len() > PATH_HEADER_SIZE,
|
geometry.len() > PATH_HEADER_SIZE,
|
||||||
@ -89,7 +127,8 @@ pub fn wrap_path<'a>(geometry: &'a mut [i32]) -> PathData<'a> {
|
|||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
points_slice.len() % 4 == 0,
|
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;
|
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())
|
std::slice::from_raw_parts_mut(points_slice.as_mut_ptr() as *mut f32, points_slice.len())
|
||||||
};
|
};
|
||||||
|
|
||||||
PathData {
|
PathDataMut {
|
||||||
header,
|
depth: header[1],
|
||||||
length,
|
length,
|
||||||
points,
|
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]
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::decode_float;
|
use crate::decode_float;
|
||||||
|
|
||||||
pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
|
pub fn split_args(args: &[i32]) -> Vec<&[i32]> {
|
||||||
println!("-------------------");
|
println!("-------------------");
|
||||||
println!("{:?}", args);
|
println!("{:?}", args);
|
||||||
|
|
||||||
@ -47,15 +47,13 @@ pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
|
|||||||
}
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else if depth == 1 {
|
||||||
if depth == 1 {
|
|
||||||
out_args.push(&args[i..i + 1]);
|
out_args.push(&args[i..i + 1]);
|
||||||
println!("-> {:?}", &args[i..i + 1]);
|
println!("-> {:?}", &args[i..i + 1]);
|
||||||
start_index = i + 1;
|
start_index = i + 1;
|
||||||
} else {
|
} else {
|
||||||
println!("{}", val);
|
println!("{}", val);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
@ -63,6 +61,46 @@ pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
|
|||||||
out_args
|
out_args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn concat_arg_vecs(data: Vec<Vec<i32>>) -> Vec<i32> {
|
||||||
|
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<i32> {
|
pub fn concat_args(mut data: Vec<&[i32]>) -> Vec<i32> {
|
||||||
let mut total_length = 4; // Start with 4 to account for [0, 1] at the start and [1, 1] at the end
|
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<f32> {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = get_args(input_args);
|
let args = split_args(input_args);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
args.len() == 3,
|
args.len() == 3,
|
||||||
@ -156,7 +194,7 @@ pub fn evaluate_int(input_args: &[i32]) -> i32 {
|
|||||||
return input_args[0];
|
return input_args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = get_args(input_args);
|
let args = split_args(input_args);
|
||||||
|
|
||||||
let mut resolved: Vec<i32> = Vec::new();
|
let mut resolved: Vec<i32> = Vec::new();
|
||||||
|
|
||||||
@ -192,7 +230,7 @@ mod tests {
|
|||||||
1053609165, 54,
|
1053609165, 54,
|
||||||
];
|
];
|
||||||
|
|
||||||
let args = get_args(&input);
|
let args = split_args(&input);
|
||||||
println!("{:?}", args[0]);
|
println!("{:?}", args[0]);
|
||||||
|
|
||||||
assert_eq!(args[0].len(), 29);
|
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];
|
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]]
|
// -> [1, 2, 3, [1, 2, 4, 2, 4]]
|
||||||
|
|
||||||
let args = get_args(&input_a);
|
let args = split_args(&input_a);
|
||||||
|
|
||||||
println!("{:?}", args);
|
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];
|
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]]
|
// -> [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.len(), 5);
|
||||||
assert_eq!(args[0], [7]);
|
assert_eq!(args[0], [7]);
|
||||||
@ -258,14 +296,14 @@ mod tests {
|
|||||||
// 2 -> first number
|
// 2 -> first number
|
||||||
// 3 -> second number
|
// 3 -> second number
|
||||||
|
|
||||||
let args = get_args(&input);
|
let args = split_args(&input);
|
||||||
|
|
||||||
assert_eq!(args.len(), 4);
|
assert_eq!(args.len(), 4);
|
||||||
assert_eq!(args[0], [0]);
|
assert_eq!(args[0], [0]);
|
||||||
assert_eq!(args[1], [2]);
|
assert_eq!(args[1], [2]);
|
||||||
assert_eq!(args[3], [0, 3, 0, 128]);
|
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);
|
assert_eq!(nested_args.len(), 4);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user