feat: add snapToGrid and showGrid settings
This commit is contained in:
parent
ad197db873
commit
1de0094c85
28
Cargo.lock
generated
28
Cargo.lock
generated
@ -159,6 +159,20 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "noise"
|
||||
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"
|
||||
@ -301,20 +315,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"
|
||||
|
@ -1,7 +1,12 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["nodes/max/plantarium/*", "packages/macros", "packages/types", "packages/utils"]
|
||||
|
||||
members = [
|
||||
"nodes/max/plantarium/*",
|
||||
"packages/macros",
|
||||
"packages/types",
|
||||
"packages/utils",
|
||||
]
|
||||
exclude = ["nodes/max/plantarium/.template"]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
@ -67,27 +67,27 @@ void main(void) {
|
||||
|
||||
|
||||
//extra small grid
|
||||
float m1 = grid(ux, uy, divisions*4.0, thickness*4.0) * 0.1;
|
||||
float m2 = grid(ux, uy, divisions*16.0, thickness*16.0) * 0.03;
|
||||
float m1 = grid(ux, uy, divisions*4.0, thickness*4.0) * 0.9;
|
||||
float m2 = grid(ux, uy, divisions*16.0, thickness*16.0) * 0.5;
|
||||
float xsmall = max(m1, m2);
|
||||
|
||||
float s3 = circle_grid(ux, uy, cz/1.6, 1.0) * 0.2;
|
||||
float s3 = circle_grid(ux, uy, cz/1.6, 1.0) * 0.5;
|
||||
xsmall = max(xsmall, s3);
|
||||
|
||||
// small grid
|
||||
float c1 = grid(ux, uy, divisions, thickness) * 0.2;
|
||||
float c2 = grid(ux, uy, divisions*2.0, thickness) * 0.1;
|
||||
float c1 = grid(ux, uy, divisions, thickness) * 0.6;
|
||||
float c2 = grid(ux, uy, divisions*2.0, thickness) * 0.5;
|
||||
float small = max(c1, c2);
|
||||
|
||||
float s1 = circle_grid(ux, uy, cz*10.0, 2.0) * 0.2;
|
||||
float s1 = circle_grid(ux, uy, cz*10.0, 2.0) * 0.5;
|
||||
small = max(small, s1);
|
||||
|
||||
// large grid
|
||||
float c3 = grid(ux, uy, divisions/8.0, thickness/8.0) * 0.1;
|
||||
float c4 = grid(ux, uy, divisions/2.0, thickness/4.0) * 0.05;
|
||||
float c3 = grid(ux, uy, divisions/8.0, thickness/8.0) * 0.5;
|
||||
float c4 = grid(ux, uy, divisions/2.0, thickness/4.0) * 0.4;
|
||||
float large = max(c3, c4);
|
||||
|
||||
float s2 = circle_grid(ux, uy, cz*20.0, 1.0) * 0.2;
|
||||
float s2 = circle_grid(ux, uy, cz*20.0, 1.0) * 0.4;
|
||||
large = max(large, s2);
|
||||
|
||||
float c = mix(large, small, min(nz*2.0+0.05, 1.0));
|
||||
|
@ -53,7 +53,7 @@
|
||||
}}
|
||||
uniforms.camPos.value={cameraPosition}
|
||||
uniforms.backgroundColor.value={$colors.layer0}
|
||||
uniforms.lineColor.value={$colors.layer2}
|
||||
uniforms.lineColor.value={$colors.outline}
|
||||
uniforms.zoomLimits.value={[minZoom, maxZoom]}
|
||||
uniforms.dimensions.value={[width, height]}
|
||||
/>
|
||||
|
@ -25,6 +25,11 @@
|
||||
|
||||
export let graph: GraphManager;
|
||||
|
||||
export let settings = {
|
||||
snapToGrid: true,
|
||||
showGrid: true,
|
||||
};
|
||||
|
||||
let keymap =
|
||||
getContext<ReturnType<typeof createKeyMap>>("keymap") || createKeyMap([]);
|
||||
|
||||
@ -320,8 +325,10 @@
|
||||
|
||||
if (event.ctrlKey) {
|
||||
const snapLevel = getSnapLevel();
|
||||
newX = snapToGrid(newX, 5 / snapLevel);
|
||||
newY = snapToGrid(newY, 5 / snapLevel);
|
||||
if (settings.snapToGrid) {
|
||||
newX = snapToGrid(newX, 5 / snapLevel);
|
||||
newY = snapToGrid(newY, 5 / snapLevel);
|
||||
}
|
||||
}
|
||||
|
||||
if (!node.tmp.isMoving) {
|
||||
@ -667,15 +674,20 @@
|
||||
if (activeNode?.tmp?.isMoving) {
|
||||
activeNode.tmp = activeNode.tmp || {};
|
||||
activeNode.tmp.isMoving = false;
|
||||
const snapLevel = getSnapLevel();
|
||||
activeNode.position[0] = snapToGrid(
|
||||
activeNode?.tmp?.x ?? activeNode.position[0],
|
||||
5 / snapLevel,
|
||||
);
|
||||
activeNode.position[1] = snapToGrid(
|
||||
activeNode?.tmp?.y ?? activeNode.position[1],
|
||||
5 / snapLevel,
|
||||
);
|
||||
if (settings.snapToGrid) {
|
||||
const snapLevel = getSnapLevel();
|
||||
activeNode.position[0] = snapToGrid(
|
||||
activeNode?.tmp?.x ?? activeNode.position[0],
|
||||
5 / snapLevel,
|
||||
);
|
||||
activeNode.position[1] = snapToGrid(
|
||||
activeNode?.tmp?.y ?? activeNode.position[1],
|
||||
5 / snapLevel,
|
||||
);
|
||||
} else {
|
||||
activeNode.position[0] = activeNode?.tmp?.x ?? activeNode.position[0];
|
||||
activeNode.position[1] = activeNode?.tmp?.y ?? activeNode.position[1];
|
||||
}
|
||||
const nodes = [
|
||||
...[...($selectedNodes?.values() || [])].map((id) => graph.getNode(id)),
|
||||
] as NodeType[];
|
||||
@ -796,11 +808,9 @@
|
||||
const wrapper = createWasmWrapper(buffer);
|
||||
const definition = wrapper.get_definition();
|
||||
const res = NodeDefinitionSchema.parse(definition);
|
||||
console.log(wrapper, res);
|
||||
}
|
||||
};
|
||||
reader.readAsArrayBuffer(files[0]);
|
||||
console.log({ files });
|
||||
}
|
||||
}
|
||||
|
||||
@ -858,7 +868,9 @@
|
||||
<Canvas shadows={false} renderMode="on-demand" colorManagementEnabled={false}>
|
||||
<Camera bind:camera position={cameraPosition} />
|
||||
|
||||
<Background {cameraPosition} {maxZoom} {minZoom} {width} {height} />
|
||||
{#if settings?.showGrid !== false}
|
||||
<Background {cameraPosition} {maxZoom} {minZoom} {width} {height} />
|
||||
{/if}
|
||||
|
||||
{#if boxSelection && mouseDown}
|
||||
<BoxSelection
|
||||
|
@ -18,6 +18,9 @@
|
||||
export const keymap = createKeyMap([]);
|
||||
setContext("keymap", keymap);
|
||||
|
||||
export let showGrid = false;
|
||||
export let snapToGrid = false;
|
||||
|
||||
const updateSettings = debounce((s) => {
|
||||
manager.setSettings(s);
|
||||
}, 200);
|
||||
@ -43,4 +46,4 @@
|
||||
const dispatch = createEventDispatcher();
|
||||
</script>
|
||||
|
||||
<GraphEl graph={manager} />
|
||||
<GraphEl graph={manager} settings={{ showGrid, snapToGrid }} />
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Graph, NodeRegistry, NodeDefinition, RuntimeExecutor } from "@nodes/types";
|
||||
import { fastHash, concat_encoded, encodeFloat, encode } from "@nodes/utils"
|
||||
import { fastHash, concatEncodedArrays, encodeFloat, encodeNestedArray, decodeNestedArray } from "@nodes/utils"
|
||||
|
||||
export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
|
||||
@ -109,7 +109,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
const sortedNodes = nodes.sort((a, b) => (b.tmp?.depth || 0) - (a.tmp?.depth || 0));
|
||||
|
||||
// here we store the intermediate results of the nodes
|
||||
const results: Record<string, string | boolean | number> = {};
|
||||
const results: Record<string, Int32Array> = {};
|
||||
|
||||
const runSeed = settings["randomSeed"] === true ? Math.floor(Math.random() * 100000000) : 5120983;
|
||||
|
||||
@ -192,7 +192,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return encode(value);
|
||||
return encodeNestedArray(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -204,10 +204,14 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
|
||||
// console.log(`${a2 - a1}ms TRANSFORMED_INPUTS`);
|
||||
|
||||
const _inputs = concat_encoded(transformed_inputs);
|
||||
const encoded_inputs = concatEncodedArrays(transformed_inputs);
|
||||
const a3 = performance.now();
|
||||
// console.log(`executing ${node_type.id || node.id}`, _inputs);
|
||||
results[node.id] = node_type.execute(_inputs) as number;
|
||||
console.groupCollapsed(`executing ${node_type.id || node.id}`);
|
||||
console.log(`Inputs:`, transformed_inputs);
|
||||
console.log(`Encoded Inputs:`, encoded_inputs);
|
||||
results[node.id] = node_type.execute(encoded_inputs);
|
||||
console.log("Result:", decodeNestedArray(results[node.id]));
|
||||
console.groupEnd();
|
||||
const duration = performance.now() - a3;
|
||||
if (duration > 5) {
|
||||
this.cache[cacheKey] = { eol: Date.now() + 10_000, value: results[node.id] };
|
||||
@ -217,6 +221,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
const a4 = performance.now();
|
||||
// console.log(`${a4 - a0}ms e2e duration`);
|
||||
} catch (e) {
|
||||
console.groupEnd();
|
||||
console.error(`Error executing node ${node_type.id || node.id}`, e);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
import localStore from "$lib/helpers/localStore";
|
||||
import { label } from "three/examples/jsm/nodes/Nodes.js";
|
||||
|
||||
export const AppSettings = localStore("node-settings", {
|
||||
theme: 0,
|
||||
showGrid: true,
|
||||
showNodeGrid: true,
|
||||
snapToGrid: true,
|
||||
wireframes: false,
|
||||
showIndices: false,
|
||||
});
|
||||
@ -33,6 +34,16 @@ export const AppSettingTypes = {
|
||||
label: "Show Grid",
|
||||
value: true,
|
||||
},
|
||||
nodeInterface: {
|
||||
showNodeGrid: {
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
snapToGrid: {
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
},
|
||||
stressTest: {
|
||||
amount: {
|
||||
type: "integer",
|
||||
|
@ -14,10 +14,13 @@
|
||||
import NodeStore from "$lib/node-store/NodeStore.svelte";
|
||||
import type { GraphManager } from "$lib/graph-interface/graph-manager";
|
||||
import { setContext } from "svelte";
|
||||
import { decodeNestedArray } from "@nodes/utils";
|
||||
|
||||
const nodeRegistry = new RemoteNodeRegistry("");
|
||||
const runtimeExecutor = new MemoryRuntimeExecutor(nodeRegistry);
|
||||
|
||||
globalThis.decode = decodeNestedArray;
|
||||
|
||||
let res: Int32Array;
|
||||
|
||||
let graph = localStorage.getItem("graph")
|
||||
@ -120,6 +123,8 @@
|
||||
registry={nodeRegistry}
|
||||
{graph}
|
||||
bind:keymap
|
||||
showGrid={$AppSettings?.showNodeGrid}
|
||||
snapToGrid={$AppSettings?.snapToGrid}
|
||||
settings={settings?.graph?.settings}
|
||||
on:settings={handleSettings}
|
||||
on:result={handleResult}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use macros::include_definition_file;
|
||||
use utils::{evaluate_arg, get_args};
|
||||
use utils::{evaluate_int, get_args};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use web_sys::console;
|
||||
|
||||
@ -11,8 +11,8 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||
|
||||
let args = get_args(input);
|
||||
|
||||
let value_encoded = evaluate_arg(args[0]);
|
||||
let length = evaluate_arg(args[1]) as usize;
|
||||
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());
|
||||
|
||||
|
@ -5,17 +5,13 @@ include_definition_file!("src/input.json");
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn execute(args: &[i32]) -> Vec<i32> {
|
||||
let mut result = Vec::with_capacity(args.len() + 7);
|
||||
result.push(0);
|
||||
result.push(1);
|
||||
let mut result = Vec::with_capacity(args.len() + 3);
|
||||
result.push(0); // encoding the [ bracket
|
||||
result.push(args[1] + 1);
|
||||
|
||||
result.push(0); // adding the node-type, math: 0
|
||||
result.extend_from_slice(&args[2..]);
|
||||
|
||||
result.push(1);
|
||||
result.push(1); // closing bracket
|
||||
result.push(1);
|
||||
result.push(1); // closing bracket
|
||||
result
|
||||
|
6
nodes/max/plantarium/noise/.gitignore
vendored
Normal file
6
nodes/max/plantarium/noise/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
bin/
|
||||
pkg/
|
||||
wasm-pack.log
|
28
nodes/max/plantarium/noise/Cargo.toml
Normal file
28
nodes/max/plantarium/noise/Cargo.toml
Normal file
@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "noise"
|
||||
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"
|
6
nodes/max/plantarium/noise/package.json
Normal file
6
nodes/max/plantarium/noise/package.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"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'"
|
||||
}
|
||||
}
|
21
nodes/max/plantarium/noise/src/input.json
Normal file
21
nodes/max/plantarium/noise/src/input.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"id": "max/plantarium/noise",
|
||||
"outputs": [
|
||||
"plant"
|
||||
],
|
||||
"inputs": {
|
||||
"plant": {
|
||||
"type": "plant"
|
||||
},
|
||||
"scale": {
|
||||
"type": "float",
|
||||
"min": 0.1,
|
||||
"max": 100
|
||||
},
|
||||
"strength": {
|
||||
"type": "float",
|
||||
"min": 0.1,
|
||||
"max": 100
|
||||
}
|
||||
}
|
||||
}
|
14
nodes/max/plantarium/noise/src/lib.rs
Normal file
14
nodes/max/plantarium/noise/src/lib.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use macros::include_definition_file;
|
||||
use utils::{concat_args, get_args, log};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
include_definition_file!("src/input.json");
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[wasm_bindgen]
|
||||
pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||
let args = get_args(input);
|
||||
let plants = get_args(args[0]);
|
||||
log!("noise plants: {:?}", plants);
|
||||
concat_args(vec![plants[0].to_vec()])
|
||||
}
|
13
nodes/max/plantarium/noise/tests/web.rs
Normal file
13
nodes/max/plantarium/noise/tests/web.rs
Normal file
@ -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);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use glam::{Mat4, Vec3};
|
||||
use macros::include_definition_file;
|
||||
use utils::{
|
||||
concat_args, evaluate_arg,
|
||||
concat_args, evaluate_int,
|
||||
geometry::{extrude_path, transform_geometry},
|
||||
get_args, log,
|
||||
};
|
||||
@ -10,13 +10,17 @@ use wasm_bindgen::prelude::*;
|
||||
include_definition_file!("src/inputs.json");
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn execute(input: Vec<i32>) -> Vec<i32> {
|
||||
pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||
utils::set_panic_hook();
|
||||
|
||||
let args = get_args(input.as_slice());
|
||||
log!("output input: {:?}", input);
|
||||
|
||||
let args = get_args(input);
|
||||
|
||||
log!("output args: {:?}", args);
|
||||
|
||||
let inputs = get_args(args[0]);
|
||||
let resolution = evaluate_arg(args[1]) as usize;
|
||||
let resolution = evaluate_int(args[1]) as usize;
|
||||
|
||||
log!("inputs: {}, resolution: {}", inputs.len(), resolution);
|
||||
|
||||
@ -26,13 +30,19 @@ pub fn execute(input: Vec<i32>) -> Vec<i32> {
|
||||
continue;
|
||||
}
|
||||
|
||||
if arg[2] == 0 {
|
||||
let arg_type = arg[0];
|
||||
|
||||
log!("arg: {:?}", arg);
|
||||
|
||||
if arg_type == 0 {
|
||||
// this is stem
|
||||
let _arg = &arg[3..];
|
||||
let mut geometry = extrude_path(_arg, resolution);
|
||||
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_type == 1 {
|
||||
// this is geometry
|
||||
output.push(arg.to_vec());
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use macros::include_definition_file;
|
||||
use utils::{evaluate_arg, evaluate_float, evaluate_vec3, get_args, set_panic_hook, wrap_arg};
|
||||
use utils::{evaluate_float, evaluate_int, evaluate_vec3, get_args, log, set_panic_hook, wrap_arg};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
include_definition_file!("src/input.json");
|
||||
@ -10,22 +10,30 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||
|
||||
let args = get_args(input);
|
||||
|
||||
log!("node-stem: {:?}", args);
|
||||
|
||||
let origin = evaluate_vec3(args[0]);
|
||||
let length = evaluate_float(args[1]);
|
||||
let thickness = evaluate_float(args[2]);
|
||||
let res_curve = evaluate_arg(args[3]) as usize;
|
||||
let res_curve = evaluate_int(args[3]) as usize;
|
||||
|
||||
let mut path: Vec<i32> = vec![0; res_curve * 4 + 1];
|
||||
path.resize(res_curve * 4 + 1, 0);
|
||||
log!("origin: {:?}", origin);
|
||||
|
||||
let slice = &mut path[1..];
|
||||
let amount_points = res_curve * 4;
|
||||
// +4 for opening and closing brackets and +1 node-type
|
||||
let output_size = amount_points + 5;
|
||||
|
||||
let mut path: Vec<i32> = vec![0; output_size];
|
||||
path[0] = 0; // encode opening bracket
|
||||
path[1] = res_curve as i32 * 4 + 4; // encode opening bracket
|
||||
path[2] = 0; // encode node-type, stem: 0
|
||||
path[output_size - 2] = 1; // encode closing bracket
|
||||
path[output_size - 1] = 1; // encode closing bracket
|
||||
|
||||
let slice = &mut path[3..output_size - 2];
|
||||
|
||||
// Unsafe code to transmute the i32 slice to an f32 slice
|
||||
let path_p: &mut [f32] = unsafe {
|
||||
// Ensure that the length of the slice is a multiple of 4
|
||||
assert_eq!(slice.len() % 4, 0);
|
||||
|
||||
// Transmute the i32 slice to an f32 slice
|
||||
std::slice::from_raw_parts_mut(slice.as_ptr() as *mut f32, slice.len())
|
||||
};
|
||||
|
||||
@ -37,5 +45,7 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||
path_p[i * 4 + 3] = thickness * (1.0 - a);
|
||||
}
|
||||
|
||||
wrap_arg(&path)
|
||||
log!("res: {:?}", path);
|
||||
|
||||
path
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use macros::include_definition_file;
|
||||
use utils::{decode_float, encode_float, evaluate_arg, get_args, wrap_arg};
|
||||
use utils::{decode_float, encode_float, evaluate_int, get_args, wrap_arg};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use web_sys::console;
|
||||
|
||||
@ -13,7 +13,7 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||
|
||||
let args = get_args(input);
|
||||
|
||||
let size = evaluate_arg(args[0]);
|
||||
let size = evaluate_int(args[0]);
|
||||
let decoded = decode_float(size);
|
||||
let negative_size = encode_float(-decoded);
|
||||
|
||||
|
@ -1,20 +1,9 @@
|
||||
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<i32> {
|
||||
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
|
||||
pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||
input.to_vec()
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
type SparseArray<T = number> = (T | T[] | SparseArray<T>)[];
|
||||
|
||||
export function concat_encoded(input: (number | number[])[]): number[] {
|
||||
export function concatEncodedArrays(input: (number | number[])[]): number[] {
|
||||
|
||||
if (input.length === 1 && Array.isArray(input[0])) {
|
||||
return input[0]
|
||||
@ -26,11 +26,13 @@ export function concat_encoded(input: (number | number[])[]): number[] {
|
||||
}
|
||||
}
|
||||
|
||||
result.push(1, 1); // closing bracket
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Encodes a nested array into a flat array with bracket and distance notation
|
||||
export function encode(array: SparseArray): number[] {
|
||||
export function encodeNestedArray(array: SparseArray): number[] {
|
||||
const encoded = [0, 0]; // Initialize encoded array with root bracket notation
|
||||
let missingBracketIndex = 1; // Track where to insert the distance to the next bracket
|
||||
|
||||
@ -44,7 +46,7 @@ export function encode(array: SparseArray): number[] {
|
||||
encoded.push(0, 1, 1, 1);
|
||||
} else {
|
||||
// Recursively encode non-empty arrays
|
||||
const child = encode(item);
|
||||
const child = encodeNestedArray(item);
|
||||
encoded.push(...child, 1, 0);
|
||||
}
|
||||
// Update missingBracketIndex to the position of the newly added bracket
|
||||
@ -59,7 +61,12 @@ export function encode(array: SparseArray): number[] {
|
||||
return encoded;
|
||||
};
|
||||
|
||||
function decode_recursive(dense: number[], index = 0) {
|
||||
function decode_recursive(dense: number[] | Int32Array, index = 0) {
|
||||
|
||||
if (dense instanceof Int32Array) {
|
||||
dense = Array.from(dense)
|
||||
}
|
||||
|
||||
const decoded: (number | number[])[] = [];
|
||||
let nextBracketIndex = dense[index + 1] + index + 1; // Calculate the index of the next bracket
|
||||
|
||||
@ -83,6 +90,6 @@ function decode_recursive(dense: number[], index = 0) {
|
||||
return [decoded, index, nextBracketIndex] as const;
|
||||
}
|
||||
|
||||
export function decode(dense: number[]) {
|
||||
export function decodeNestedArray(dense: number[] | Int32Array) {
|
||||
return decode_recursive(dense, 0)[0];
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec<i32> {
|
||||
let i_index_offset = index_offset + j * 6;
|
||||
let i_position_offset = position_offset + j;
|
||||
|
||||
log!("i: {}, j: {}, i_index_offset: {}, i_position_offset: {} res_x: {}", i, j, i_index_offset, i_position_offset,res_x);
|
||||
//log!("i: {}, j: {}, i_index_offset: {}, i_position_offset: {} res_x: {}", i, j, i_index_offset, i_position_offset,res_x);
|
||||
|
||||
if j == res_x - 1 {
|
||||
indices[i_index_offset ] = (i_position_offset + 1) as i32;
|
||||
|
@ -39,9 +39,13 @@ pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
|
||||
// skip over the bracket encoding
|
||||
idx += 2;
|
||||
} else {
|
||||
if depth == 1 {
|
||||
arg_start_index = idx + 2;
|
||||
}
|
||||
// skip to the next bracket if we are at depth > 0
|
||||
idx = next_bracket_index;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -56,6 +60,12 @@ pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
println!("idx: {}, length: {}, asi: {}", idx, length, arg_start_index);
|
||||
|
||||
if arg_start_index < length {
|
||||
out_args.push(&args[arg_start_index..]);
|
||||
}
|
||||
|
||||
out_args
|
||||
}
|
||||
|
||||
@ -101,6 +111,8 @@ pub fn wrap_arg(arg: &[i32]) -> Vec<i32> {
|
||||
pub fn evaluate_node(input_args: &[i32]) -> i32 {
|
||||
let node_type = input_args[0];
|
||||
|
||||
println!("node_type: {} -> {:?}", node_type, input_args);
|
||||
|
||||
match node_type {
|
||||
0 => crate::nodes::math_node(&input_args[1..]),
|
||||
1 => crate::nodes::random_node(&input_args[1..]),
|
||||
@ -109,12 +121,21 @@ pub fn evaluate_node(input_args: &[i32]) -> i32 {
|
||||
}
|
||||
|
||||
pub fn evaluate_vec3(input_args: &[i32]) -> Vec<f32> {
|
||||
if input_args.len() == 3 {
|
||||
return vec![
|
||||
decode_float(input_args[0]),
|
||||
decode_float(input_args[1]),
|
||||
decode_float(input_args[2]),
|
||||
];
|
||||
}
|
||||
|
||||
let args = get_args(input_args);
|
||||
|
||||
assert!(
|
||||
args.len() == 3,
|
||||
"Failed to evaluate Vec3 - Expected 3 arguments, got {}",
|
||||
args.len()
|
||||
"Failed to evaluate Vec3 - Expected 3 arguments, got {} \n {:?}",
|
||||
args.len(),
|
||||
args
|
||||
);
|
||||
|
||||
let x = evaluate_float(args[0]);
|
||||
@ -125,16 +146,18 @@ pub fn evaluate_vec3(input_args: &[i32]) -> Vec<f32> {
|
||||
}
|
||||
|
||||
pub fn evaluate_float(arg: &[i32]) -> f32 {
|
||||
decode_float(evaluate_arg(arg))
|
||||
decode_float(evaluate_int(arg))
|
||||
}
|
||||
|
||||
pub fn evaluate_arg(input_args: &[i32]) -> i32 {
|
||||
pub fn evaluate_int(input_args: &[i32]) -> i32 {
|
||||
if input_args.len() == 1 {
|
||||
return input_args.to_vec()[0];
|
||||
return input_args[0];
|
||||
}
|
||||
|
||||
let args = get_args(input_args);
|
||||
|
||||
println!("args: {:?}", args);
|
||||
|
||||
let mut resolved: Vec<i32> = Vec::new();
|
||||
|
||||
for arg in args {
|
||||
@ -144,7 +167,7 @@ pub fn evaluate_arg(input_args: &[i32]) -> i32 {
|
||||
resolved.push(arg[2]);
|
||||
resolved.push(arg[3]);
|
||||
} else {
|
||||
resolved.push(evaluate_arg(arg));
|
||||
resolved.push(evaluate_int(arg));
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +183,32 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[test]
|
||||
fn test_split_args() {
|
||||
let input = [
|
||||
0, 1, 0, 28, 0, 2, 1048576000, 0, 20, 0, 4, 0, 0, 1073741824, 0, 9, 0, 5, 0, 0,
|
||||
1073741824, 1073741824, 1, 1, 1, 0, 1, 1, 1, 4, 1041865114, 1, 5, 1086324736,
|
||||
1053609165, 54,
|
||||
];
|
||||
|
||||
// this should be the output
|
||||
/* [
|
||||
[ 0, 2, 1048576000, 0, 20, 0, 4, 0, 0, 1073741824, 0, 9, 0, 5, 0, 0, 1073741824, 1073741824, 1, 1, 1, 0, 1, 1, 1, 4, 1041865114 ],
|
||||
1086324736,
|
||||
1053609165,
|
||||
54
|
||||
] */
|
||||
|
||||
|
||||
let args = get_args(&input);
|
||||
println!("{:?}", args[0]);
|
||||
|
||||
assert_eq!(args[0].len(), 27);
|
||||
assert_eq!(args[1][0], 1086324736);
|
||||
assert_eq!(args[2][0], 1053609165);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recursive_evaluation() {
|
||||
let input = vec![
|
||||
|
@ -2,3 +2,4 @@ packages:
|
||||
- app
|
||||
- packages/*
|
||||
- nodes/**/**/**/*
|
||||
- '!**/.template'
|
||||
|
Loading…
Reference in New Issue
Block a user