diff --git a/Cargo.lock b/Cargo.lock
index 066c767..1f819b0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -51,6 +51,26 @@ dependencies = [
"wasm-bindgen-test",
]
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "gl_matrix"
+version = "0.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df64d0245c589931a0b5a385a63e7db2aeff209bdd471df0417e0f230a4c33ae"
+dependencies = [
+ "rand",
+]
+
[[package]]
name = "itoa"
version = "1.0.11"
@@ -66,6 +86,12 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "libc"
+version = "0.2.153"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+
[[package]]
name = "log"
version = "0.4.21"
@@ -116,6 +142,12 @@ dependencies = [
"web-sys",
]
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
[[package]]
name = "proc-macro2"
version = "1.0.80"
@@ -134,6 +166,47 @@ dependencies = [
"proc-macro2",
]
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom",
+ "libc",
+ "rand_chacha",
+ "rand_core",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core",
+]
+
[[package]]
name = "random"
version = "0.1.0"
@@ -274,11 +347,18 @@ name = "utils"
version = "0.1.0"
dependencies = [
"console_error_panic_hook",
+ "gl_matrix",
"serde",
"serde_json",
"wasm-bindgen",
]
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
[[package]]
name = "wasm-bindgen"
version = "0.2.92"
diff --git a/app/src/lib/graph-interface/graph/Graph.svelte b/app/src/lib/graph-interface/graph/Graph.svelte
index 34740c0..ead4ea0 100644
--- a/app/src/lib/graph-interface/graph/Graph.svelte
+++ b/app/src/lib/graph-interface/graph/Graph.svelte
@@ -403,8 +403,6 @@
function handleMouseDown(event: MouseEvent) {
if (mouseDown) return;
- console.log(event.target);
-
if (event.target instanceof HTMLElement) {
if (
event.target.nodeName !== "CANVAS" &&
diff --git a/app/src/lib/helpers/encode.test.ts b/app/src/lib/helpers/encode.test.ts
index 6e99436..8813c61 100644
--- a/app/src/lib/helpers/encode.test.ts
+++ b/app/src/lib/helpers/encode.test.ts
@@ -4,7 +4,7 @@ import { encodeFloat, decodeFloat } from "./encode"
test("encode_float", () => {
const input = 1.23;
const encoded = encodeFloat(input)
- const output = decodeFloat(encoded[0], encoded[1])
+ const output = decodeFloat(encoded)
console.log(input, output)
expect(output).toBeCloseTo(input);
});
@@ -12,7 +12,7 @@ test("encode_float", () => {
test("encode 2.0", () => {
const input = 2.0;
const encoded = encodeFloat(input)
- expect(encoded).toEqual([0, 128])
+ expect(encoded).toEqual(1073741824)
});
test("floating point imprecision", () => {
@@ -20,7 +20,7 @@ test("floating point imprecision", () => {
new Array(10_000).fill(null).forEach((_, i) => {
const input = i < 5_000 ? i : Math.random() * 100;
const encoded = encodeFloat(input);
- const output = decodeFloat(encoded[0], encoded[1]);
+ const output = decodeFloat(encoded);
const error = Math.abs(input - output);
if (error > maxError) {
@@ -36,7 +36,7 @@ test("negative numbers", () => {
const inputs = [-1, -0.5, -123.456, -0.0001];
inputs.forEach(input => {
const encoded = encodeFloat(input);
- const output = decodeFloat(encoded[0], encoded[1]);
+ const output = decodeFloat(encoded);
expect(output).toBeCloseTo(input);
});
});
@@ -45,7 +45,7 @@ test("negative numbers", () => {
test("very small numbers", () => {
const input = 1.2345e-38;
const encoded = encodeFloat(input)
- const output = decodeFloat(encoded[0], encoded[1])
+ const output = decodeFloat(encoded)
expect(output).toBeCloseTo(input);
});
@@ -53,7 +53,7 @@ test("very small numbers", () => {
test("zero", () => {
const input = 0;
const encoded = encodeFloat(input)
- const output = decodeFloat(encoded[0], encoded[1])
+ const output = decodeFloat(encoded)
expect(output).toBe(0);
});
@@ -61,7 +61,7 @@ test("zero", () => {
test("infinity", () => {
const input = Infinity;
const encoded = encodeFloat(input)
- const output = decodeFloat(encoded[0], encoded[1])
+ const output = decodeFloat(encoded)
expect(output).toBe(Infinity);
});
@@ -70,7 +70,7 @@ test("large numbers", () => {
const inputs = [1e+5, 1e+10];
inputs.forEach(input => {
const encoded = encodeFloat(input);
- const output = decodeFloat(encoded[0], encoded[1]);
+ const output = decodeFloat(encoded);
// Note: Large numbers may lose precision, hence using toBeCloseTo with a tolerance
expect(output).toBeCloseTo(input, 0);
});
diff --git a/app/src/lib/helpers/encode.ts b/app/src/lib/helpers/encode.ts
index 49fd6b1..d5f77ab 100644
--- a/app/src/lib/helpers/encode.ts
+++ b/app/src/lib/helpers/encode.ts
@@ -1,34 +1,19 @@
+// Create a buffer to hold the float as bytes
+const buffer = new ArrayBuffer(4);
+const view = new DataView(buffer);
-export function encodeFloat(f: number): [number, number] {
- let buffer = new ArrayBuffer(4); // Create a buffer of 4 bytes (32 bits)
- let floatView = new Float32Array(buffer);
- let intView = new Uint32Array(buffer);
+export function encodeFloat(value: number): number {
+ // Write the number as a float to the buffer
+ view.setFloat32(0, value, true); // 'true' for little-endian
- floatView[0] = f; // Store the float into the buffer
- let bits = intView[0]; // Read the bits as integer
-
- let mantissa = bits & 0x007FFFFF;
- let exponent = (bits >> 23) & 0xFF;
- let sign = (f < 0.0) ? 1 : 0;
-
- // Include the sign bit in the mantissa
- mantissa = mantissa | (sign << 23);
-
- return [mantissa, exponent];
+ // Read the buffer as an integer
+ return view.getInt32(0, true);
}
-export function decodeFloat(mantissa: number, exponent: number): number {
- let signBit = (mantissa >> 23) & 1;
- let mantissaBits = mantissa & 0x007FFFFF;
- let exponentBits = (exponent & 0xFF) << 23;
+export function decodeFloat(value: number): number {
+ // Write the integer back as an int32
+ view.setInt32(0, value, true);
- // Reconstruct all bits including sign
- let bits = (signBit << 31) | exponentBits | mantissaBits;
-
- let buffer = new ArrayBuffer(4);
- let floatView = new Float32Array(buffer);
- let intView = new Uint32Array(buffer);
-
- intView[0] = bits; // Set the bits as integer
- return floatView[0]; // Read the float back from the buffer
+ // Read the buffer as a float
+ return view.getFloat32(0, true);
}
diff --git a/app/src/lib/runtime-executor.ts b/app/src/lib/runtime-executor.ts
index b71f59d..5753a94 100644
--- a/app/src/lib/runtime-executor.ts
+++ b/app/src/lib/runtime-executor.ts
@@ -1,7 +1,7 @@
import type { Graph, NodeRegistry, NodeType, RuntimeExecutor } from "@nodes/types";
import { encodeFloat } from "./helpers/encode";
-import { concat_encoded, encode } from "./helpers/flat_tree";
-import { fastHash, fastHashString } from "./helpers/fastHash";
+import { concat_encoded } from "./helpers/flat_tree";
+import { fastHash } from "./helpers/fastHash";
@@ -179,7 +179,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
}
if (input_type.type === "float") {
- return encode(encodeFloat(value as number));
+ return encodeFloat(value as number);
}
return value;
@@ -208,9 +208,9 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
}
// return the result of the parent of the output node
- const res = results[outputNode.id] as string
+ const res = results[outputNode.id];
- return res;
+ return res as unknown as Int32Array;
}
diff --git a/app/src/lib/viewer/Scene.svelte b/app/src/lib/viewer/Scene.svelte
new file mode 100644
index 0000000..83950c6
--- /dev/null
+++ b/app/src/lib/viewer/Scene.svelte
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+{#each geometry as geo}
+
+
+
+{:else}
+
+
+
+
+{/each}
diff --git a/app/src/lib/viewer/Viewer.svelte b/app/src/lib/viewer/Viewer.svelte
new file mode 100644
index 0000000..ddeda81
--- /dev/null
+++ b/app/src/lib/viewer/Viewer.svelte
@@ -0,0 +1,117 @@
+
+
+
+
+
diff --git a/app/src/routes/+page.svelte b/app/src/routes/+page.svelte
index a770278..fbf69f4 100644
--- a/app/src/routes/+page.svelte
+++ b/app/src/routes/+page.svelte
@@ -6,15 +6,18 @@
import * as templates from "$lib/graph-templates";
import type { Graph } from "@nodes/types";
import { decode, encode } from "$lib/helpers/flat_tree";
- import { decodeFloat } from "$lib/helpers/encode";
+ import { decodeFloat, encodeFloat } from "$lib/helpers/encode";
+ import Viewer from "$lib/viewer/Viewer.svelte";
globalThis.decode = decode;
globalThis.encode = encode;
+ globalThis.df = decodeFloat;
+ globalThis.en = encodeFloat;
const nodeRegistry = new RemoteNodeRegistry("http://localhost:3001");
const runtimeExecutor = new MemoryRuntimeExecutor(nodeRegistry);
- let res = "2";
+ let res: Int32Array;
let time = 0;
let graph = localStorage.getItem("graph")
@@ -23,13 +26,7 @@
function handleResult(event: CustomEvent) {
let a = performance.now();
- let _res: any = runtimeExecutor.execute(event.detail);
- if (_res instanceof Int32Array) {
- const f = decodeFloat(_res[0], _res[1]);
- res = Math.round(f * 100_000) / 100_000;
- } else {
- res = _res;
- }
+ res = runtimeExecutor.execute(event.detail);
time = performance.now() - a;
console.log(res);
}
@@ -50,9 +47,7 @@
- result: {res}
-
- time: {time}ms
+
{#key graph}
diff --git a/nodes/max/plantarium/output/src/inputs.json b/nodes/max/plantarium/output/src/inputs.json
index 16922a7..8399f1c 100644
--- a/nodes/max/plantarium/output/src/inputs.json
+++ b/nodes/max/plantarium/output/src/inputs.json
@@ -2,7 +2,7 @@
"outputs": [],
"inputs": {
"input": {
- "type": "plant",
+ "type": "float",
"external": true
}
}
diff --git a/nodes/max/plantarium/output/src/lib.rs b/nodes/max/plantarium/output/src/lib.rs
index 973d201..6212e04 100644
--- a/nodes/max/plantarium/output/src/lib.rs
+++ b/nodes/max/plantarium/output/src/lib.rs
@@ -1,16 +1,48 @@
use macros::include_definition_file;
-use utils::evaluate_args;
+use utils::{decode_float, encode_float};
use wasm_bindgen::prelude::*;
+use web_sys::console;
include_definition_file!("src/inputs.json");
+#[rustfmt::skip]
#[wasm_bindgen]
-pub fn execute(args: &[i32]) -> Vec {
+pub fn execute(input: &[i32]) -> Vec {
utils::set_panic_hook();
- // console::log_1(&format!("WASM(output_node): input: {:?}", args).into());
+ let size = input[2];
+ let decoded = decode_float(input[2]);
+ let negative_size = encode_float(-decoded);
+
+ console::log_1(&format!("WASM(output_node): input: {:?} -> {}", input, decoded).into());
+
+ // [[1,3, x, y, z, x, y,z,x,y,z]];
+ vec![
+ 0, 1, // opening bracket
+ 0, 19, // opening bracket + distance to next bracket
+ 1, // 1: geometry
+ 3, // 3 vertices
+ 1, // 1 face
+ // thise are the indeces for the face
+ 0, 2, 1,
+ // this is the normal for the single face 1065353216 == 1.0f encoded is i32
+ 0, 1065353216, 0,
+ //
+ negative_size, // x -> point 1
+ 0, // y
+ 0, // z
+ //
+ size, // x -> point 2
+ 0, // y
+ 0, // z
+ //
+ 0, // x -> point 3
+ 0, // y
+ size, // z
+ //
+ 1, 1, 1, 1, // closing brackets
+ ]
- evaluate_args(args)
// let decoded = decode_float(result[0], result[1]);
// console::log_1(&format!("WASM: output: {:?}", decoded).into());
diff --git a/nodes/max/plantarium/stem/src/lib.rs b/nodes/max/plantarium/stem/src/lib.rs
index 49bf1f6..d9deefb 100644
--- a/nodes/max/plantarium/stem/src/lib.rs
+++ b/nodes/max/plantarium/stem/src/lib.rs
@@ -11,7 +11,7 @@ pub fn execute(input: &[i32]) -> Vec {
let length = evaluate_args(args[0]);
let thickness = evaluate_args(args[1]);
- let resolution = evaluate_args(args[2]);
+ let resolution = 32; //evaluate_args(args[2]);
console::log_1(
&format!(
@@ -21,14 +21,20 @@ pub fn execute(input: &[i32]) -> Vec {
.into(),
);
- let mut result: Vec = Vec::with_capacity(args.len() + 3);
-
- result.push(0); // encoding the [ bracket
- result.push(2);
- result.push(0); // adding the node-type, math: 0
- result.extend_from_slice(&thickness);
- result.push(1);
- result.push(1); // closing bracket
-
- result
+ vec![
+ 0, // opening bracket
+ 11, // opening bracket
+ 0, // type: plant
+ 0, // alpha: 0
+ 0, // x
+ 0, // y
+ 0, // z
+ 1, // thickness
+ 0, // x
+ 2, // y
+ 0, // z
+ 1, // thickness
+ 1, // closing bracket
+ 1, //closing bracket
+ ]
}
diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml
index c4327ea..96928b5 100644
--- a/packages/utils/Cargo.toml
+++ b/packages/utils/Cargo.toml
@@ -11,3 +11,4 @@ wasm-bindgen = "0.2.92"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
console_error_panic_hook = { version = "0.1.7", optional = true }
+gl_matrix = "0.0.2"
diff --git a/packages/utils/src/encoding.rs b/packages/utils/src/encoding.rs
index a6344fa..98ba5c3 100644
--- a/packages/utils/src/encoding.rs
+++ b/packages/utils/src/encoding.rs
@@ -1,16 +1,12 @@
-pub fn encode_float(f: f32) -> (i32, i32) {
+pub fn encode_float(f: f32) -> i32 {
+ // Convert f32 to u32 using to_bits, then safely cast to i32
let bits = f.to_bits();
- let mantissa = (bits & 0x007FFFFF) as i32;
- let exponent = ((bits >> 23) & 0xFF) as i32;
- let sign = if f < 0.0 { 1 } else { 0 }; // Determine sign as 1 for negative, 0 for positive
- (mantissa | (sign << 23), exponent) // Include the sign bit in the mantissa
+ bits as i32
}
-pub fn decode_float(mantissa: i32, exponent: i32) -> f32 {
- let sign_bit = ((mantissa >> 23) & 1) as u32; // Extract the sign bit
- let mantissa_bits = (mantissa & 0x007FFFFF) as u32;
- let exponent_bits = (exponent as u32 & 0xFF) << 23;
- let bits = (sign_bit << 31) | exponent_bits | mantissa_bits; // Reconstruct all bits including sign
+pub fn decode_float(bits: i32) -> f32 {
+ // Convert i32 to u32 safely, then use from_bits to get f32
+ let bits = bits as u32;
f32::from_bits(bits)
}
@@ -18,20 +14,24 @@ pub fn decode_float(mantissa: i32, exponent: i32) -> f32 {
mod tests {
use super::*;
- #[rustfmt::skip]
#[test]
- fn test_encode_decode() {
- let original_floats = [
- 0.0, 1.0, -1.0, 123.456, -123.456, 1e-10, -1e10, f32::MAX, f32::MIN,
+ fn test_decode_float_simple() {
+ let test_values: [f32; 6] = [
+ 0.0,
+ -0.0,
+ 123.456,
+ -123.456,
+ std::f32::INFINITY,
+ std::f32::NEG_INFINITY,
];
- for &original in &original_floats {
- let (mantissa, exponent) = encode_float(original);
- let decoded = decode_float(mantissa, exponent);
- assert!(
- (decoded - original).abs() < 1e-6,
- "Mismatch: original {} vs decoded {}",
- original,
- decoded
+ for &value in &test_values {
+ let encoded = encode_float(value);
+ let decoded = decode_float(encoded);
+ assert_eq!(
+ decoded.to_bits(),
+ value.to_bits(),
+ "Failed for value {}",
+ value
);
}
}
diff --git a/packages/utils/src/geometry/extrude_path.rs b/packages/utils/src/geometry/extrude_path.rs
new file mode 100644
index 0000000..9f257c2
--- /dev/null
+++ b/packages/utils/src/geometry/extrude_path.rs
@@ -0,0 +1,2 @@
+pub fn extrude_path(path: &[i32]) {}
+
diff --git a/packages/utils/src/nodes.rs b/packages/utils/src/nodes.rs
index d69beee..cf3d203 100644
--- a/packages/utils/src/nodes.rs
+++ b/packages/utils/src/nodes.rs
@@ -1,10 +1,10 @@
use crate::encoding;
-pub fn math_node(args: &[i32]) -> (i32, i32) {
+pub fn math_node(args: &[i32]) -> i32 {
let math_type = args[0];
- let a = encoding::decode_float(args[1], args[2]);
- let b = encoding::decode_float(args[3], args[4]);
+ let a = encoding::decode_float(args[1]);
+ let b = encoding::decode_float(args[2]);
let result = match math_type {
0 => a + b,
diff --git a/packages/utils/src/tree.rs b/packages/utils/src/tree.rs
index 134e50f..a931a4d 100644
--- a/packages/utils/src/tree.rs
+++ b/packages/utils/src/tree.rs
@@ -57,12 +57,12 @@ pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
out_args
}
-pub fn evaluate_node(input_args: &[i32]) -> (i32, i32) {
+pub fn evaluate_node(input_args: &[i32]) -> i32 {
let node_type = input_args[0];
match node_type {
0 => crate::nodes::math_node(&input_args[1..]),
- _ => (0, 0),
+ _ => 0,
}
}
@@ -92,7 +92,7 @@ pub fn evaluate_args(input_args: &[i32]) -> Vec {
if resolved.len() > 1 {
let res = evaluate_node(&resolved);
- vec![res.0, res.1]
+ vec![res]
} else {
resolved
}
@@ -112,7 +112,7 @@ mod tests {
// the numbers are f32 floats encoded as two i32's
let result = evaluate_args(&input);
- let decoded = decode_float(result[0], result[1]);
+ let decoded = decode_float(result[0]);
assert_eq!(decoded, 6.0);
}