feat: yaaay a triangle :)))
This commit is contained in:
parent
8f594aebe3
commit
ddd0e6a0cf
80
Cargo.lock
generated
80
Cargo.lock
generated
@ -51,6 +51,26 @@ dependencies = [
|
|||||||
"wasm-bindgen-test",
|
"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]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
@ -66,6 +86,12 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.153"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.21"
|
version = "0.4.21"
|
||||||
@ -116,6 +142,12 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.80"
|
version = "1.0.80"
|
||||||
@ -134,6 +166,47 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"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]]
|
[[package]]
|
||||||
name = "random"
|
name = "random"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -274,11 +347,18 @@ name = "utils"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
|
"gl_matrix",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"wasm-bindgen",
|
"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]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.92"
|
version = "0.2.92"
|
||||||
|
@ -403,8 +403,6 @@
|
|||||||
function handleMouseDown(event: MouseEvent) {
|
function handleMouseDown(event: MouseEvent) {
|
||||||
if (mouseDown) return;
|
if (mouseDown) return;
|
||||||
|
|
||||||
console.log(event.target);
|
|
||||||
|
|
||||||
if (event.target instanceof HTMLElement) {
|
if (event.target instanceof HTMLElement) {
|
||||||
if (
|
if (
|
||||||
event.target.nodeName !== "CANVAS" &&
|
event.target.nodeName !== "CANVAS" &&
|
||||||
|
@ -4,7 +4,7 @@ import { encodeFloat, decodeFloat } from "./encode"
|
|||||||
test("encode_float", () => {
|
test("encode_float", () => {
|
||||||
const input = 1.23;
|
const input = 1.23;
|
||||||
const encoded = encodeFloat(input)
|
const encoded = encodeFloat(input)
|
||||||
const output = decodeFloat(encoded[0], encoded[1])
|
const output = decodeFloat(encoded)
|
||||||
console.log(input, output)
|
console.log(input, output)
|
||||||
expect(output).toBeCloseTo(input);
|
expect(output).toBeCloseTo(input);
|
||||||
});
|
});
|
||||||
@ -12,7 +12,7 @@ test("encode_float", () => {
|
|||||||
test("encode 2.0", () => {
|
test("encode 2.0", () => {
|
||||||
const input = 2.0;
|
const input = 2.0;
|
||||||
const encoded = encodeFloat(input)
|
const encoded = encodeFloat(input)
|
||||||
expect(encoded).toEqual([0, 128])
|
expect(encoded).toEqual(1073741824)
|
||||||
});
|
});
|
||||||
|
|
||||||
test("floating point imprecision", () => {
|
test("floating point imprecision", () => {
|
||||||
@ -20,7 +20,7 @@ test("floating point imprecision", () => {
|
|||||||
new Array(10_000).fill(null).forEach((_, i) => {
|
new Array(10_000).fill(null).forEach((_, i) => {
|
||||||
const input = i < 5_000 ? i : Math.random() * 100;
|
const input = i < 5_000 ? i : Math.random() * 100;
|
||||||
const encoded = encodeFloat(input);
|
const encoded = encodeFloat(input);
|
||||||
const output = decodeFloat(encoded[0], encoded[1]);
|
const output = decodeFloat(encoded);
|
||||||
|
|
||||||
const error = Math.abs(input - output);
|
const error = Math.abs(input - output);
|
||||||
if (error > maxError) {
|
if (error > maxError) {
|
||||||
@ -36,7 +36,7 @@ test("negative numbers", () => {
|
|||||||
const inputs = [-1, -0.5, -123.456, -0.0001];
|
const inputs = [-1, -0.5, -123.456, -0.0001];
|
||||||
inputs.forEach(input => {
|
inputs.forEach(input => {
|
||||||
const encoded = encodeFloat(input);
|
const encoded = encodeFloat(input);
|
||||||
const output = decodeFloat(encoded[0], encoded[1]);
|
const output = decodeFloat(encoded);
|
||||||
expect(output).toBeCloseTo(input);
|
expect(output).toBeCloseTo(input);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -45,7 +45,7 @@ test("negative numbers", () => {
|
|||||||
test("very small numbers", () => {
|
test("very small numbers", () => {
|
||||||
const input = 1.2345e-38;
|
const input = 1.2345e-38;
|
||||||
const encoded = encodeFloat(input)
|
const encoded = encodeFloat(input)
|
||||||
const output = decodeFloat(encoded[0], encoded[1])
|
const output = decodeFloat(encoded)
|
||||||
expect(output).toBeCloseTo(input);
|
expect(output).toBeCloseTo(input);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ test("very small numbers", () => {
|
|||||||
test("zero", () => {
|
test("zero", () => {
|
||||||
const input = 0;
|
const input = 0;
|
||||||
const encoded = encodeFloat(input)
|
const encoded = encodeFloat(input)
|
||||||
const output = decodeFloat(encoded[0], encoded[1])
|
const output = decodeFloat(encoded)
|
||||||
expect(output).toBe(0);
|
expect(output).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ test("zero", () => {
|
|||||||
test("infinity", () => {
|
test("infinity", () => {
|
||||||
const input = Infinity;
|
const input = Infinity;
|
||||||
const encoded = encodeFloat(input)
|
const encoded = encodeFloat(input)
|
||||||
const output = decodeFloat(encoded[0], encoded[1])
|
const output = decodeFloat(encoded)
|
||||||
expect(output).toBe(Infinity);
|
expect(output).toBe(Infinity);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ test("large numbers", () => {
|
|||||||
const inputs = [1e+5, 1e+10];
|
const inputs = [1e+5, 1e+10];
|
||||||
inputs.forEach(input => {
|
inputs.forEach(input => {
|
||||||
const encoded = encodeFloat(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
|
// Note: Large numbers may lose precision, hence using toBeCloseTo with a tolerance
|
||||||
expect(output).toBeCloseTo(input, 0);
|
expect(output).toBeCloseTo(input, 0);
|
||||||
});
|
});
|
||||||
|
@ -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] {
|
export function encodeFloat(value: number): number {
|
||||||
let buffer = new ArrayBuffer(4); // Create a buffer of 4 bytes (32 bits)
|
// Write the number as a float to the buffer
|
||||||
let floatView = new Float32Array(buffer);
|
view.setFloat32(0, value, true); // 'true' for little-endian
|
||||||
let intView = new Uint32Array(buffer);
|
|
||||||
|
|
||||||
floatView[0] = f; // Store the float into the buffer
|
// Read the buffer as an integer
|
||||||
let bits = intView[0]; // Read the bits as integer
|
return view.getInt32(0, true);
|
||||||
|
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeFloat(mantissa: number, exponent: number): number {
|
export function decodeFloat(value: number): number {
|
||||||
let signBit = (mantissa >> 23) & 1;
|
// Write the integer back as an int32
|
||||||
let mantissaBits = mantissa & 0x007FFFFF;
|
view.setInt32(0, value, true);
|
||||||
let exponentBits = (exponent & 0xFF) << 23;
|
|
||||||
|
|
||||||
// Reconstruct all bits including sign
|
// Read the buffer as a float
|
||||||
let bits = (signBit << 31) | exponentBits | mantissaBits;
|
return view.getFloat32(0, true);
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { Graph, NodeRegistry, NodeType, RuntimeExecutor } from "@nodes/types";
|
import type { Graph, NodeRegistry, NodeType, RuntimeExecutor } from "@nodes/types";
|
||||||
import { encodeFloat } from "./helpers/encode";
|
import { encodeFloat } from "./helpers/encode";
|
||||||
import { concat_encoded, encode } from "./helpers/flat_tree";
|
import { concat_encoded } from "./helpers/flat_tree";
|
||||||
import { fastHash, fastHashString } from "./helpers/fastHash";
|
import { fastHash } from "./helpers/fastHash";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (input_type.type === "float") {
|
if (input_type.type === "float") {
|
||||||
return encode(encodeFloat(value as number));
|
return encodeFloat(value as number);
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@ -208,9 +208,9 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return the result of the parent of the output node
|
// 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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
app/src/lib/viewer/Scene.svelte
Normal file
24
app/src/lib/viewer/Scene.svelte
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { T } from "@threlte/core";
|
||||||
|
import type { BufferGeometry } from "three";
|
||||||
|
import { OrbitControls } from "@threlte/extras";
|
||||||
|
|
||||||
|
export let geometry: BufferGeometry[];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<T.PerspectiveCamera position={[10, 10, 10]} makeDefault fov={50}>
|
||||||
|
<OrbitControls />
|
||||||
|
</T.PerspectiveCamera>
|
||||||
|
|
||||||
|
<T.DirectionalLight position={[0, 10, 10]} />
|
||||||
|
|
||||||
|
{#each geometry as geo}
|
||||||
|
<T.Mesh geometry={geo}>
|
||||||
|
<T.MeshBasicMaterial color="red" />
|
||||||
|
</T.Mesh>
|
||||||
|
{:else}
|
||||||
|
<T.Mesh>
|
||||||
|
<T.BoxGeometry args={[1, 1, 1]} />
|
||||||
|
<T.MeshStandardMaterial color="hotpink" />
|
||||||
|
</T.Mesh>
|
||||||
|
{/each}
|
117
app/src/lib/viewer/Viewer.svelte
Normal file
117
app/src/lib/viewer/Viewer.svelte
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Canvas } from "@threlte/core";
|
||||||
|
import Scene from "./Scene.svelte";
|
||||||
|
import { BufferGeometry, Float32BufferAttribute } from "three";
|
||||||
|
import { decodeFloat } from "$lib/helpers/encode";
|
||||||
|
|
||||||
|
export let result: Int32Array;
|
||||||
|
|
||||||
|
let geometries: BufferGeometry[] = [];
|
||||||
|
|
||||||
|
function createGeometryFromEncodedData(
|
||||||
|
encodedData: Int32Array,
|
||||||
|
): BufferGeometry {
|
||||||
|
const geometry = new BufferGeometry();
|
||||||
|
|
||||||
|
// Extract data from the encoded array
|
||||||
|
let index = 0;
|
||||||
|
const geometryType = encodedData[index++];
|
||||||
|
const vertexCount = encodedData[index++];
|
||||||
|
const faceCount = encodedData[index++];
|
||||||
|
|
||||||
|
// Indices
|
||||||
|
const indices: number[] = [];
|
||||||
|
for (let i = 0; i < faceCount * 3; i++) {
|
||||||
|
indices.push(encodedData[index++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Face normals (although typically there would be one normal per vertex)
|
||||||
|
const normals: number[] = [];
|
||||||
|
for (let i = 0; i < faceCount; i++) {
|
||||||
|
const x = decodeFloat(encodedData[index++]);
|
||||||
|
const y = decodeFloat(encodedData[index++]);
|
||||||
|
const z = decodeFloat(encodedData[index++]);
|
||||||
|
normals.push(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertices
|
||||||
|
const vertices: number[] = [];
|
||||||
|
for (let i = 0; i < vertexCount; i++) {
|
||||||
|
const x = decodeFloat(encodedData[index++]);
|
||||||
|
const y = decodeFloat(encodedData[index++]);
|
||||||
|
const z = decodeFloat(encodedData[index++]);
|
||||||
|
vertices.push(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add data to geometry
|
||||||
|
geometry.setIndex(indices);
|
||||||
|
geometry.setAttribute("position", new Float32BufferAttribute(vertices, 3));
|
||||||
|
geometry.setAttribute("normal", new Float32BufferAttribute(normals, 3));
|
||||||
|
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_args(input: Int32Array) {
|
||||||
|
let index = 0;
|
||||||
|
const length = input.length;
|
||||||
|
let res: Int32Array[] = [];
|
||||||
|
|
||||||
|
let nextBracketIndex = 0;
|
||||||
|
let argStartIndex = 0;
|
||||||
|
let depth = -1;
|
||||||
|
|
||||||
|
while (index < length) {
|
||||||
|
const value = input[index];
|
||||||
|
|
||||||
|
if (index === nextBracketIndex) {
|
||||||
|
nextBracketIndex = index + input[index + 1] + 1;
|
||||||
|
if (value === 0) {
|
||||||
|
depth++;
|
||||||
|
} else {
|
||||||
|
depth--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth === 1 && value === 0) {
|
||||||
|
// if opening bracket
|
||||||
|
argStartIndex = index + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth === 0 && value === 1) {
|
||||||
|
// if closing bracket
|
||||||
|
res.push(input.slice(argStartIndex, index));
|
||||||
|
argStartIndex = index + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = nextBracketIndex;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we should not be here
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if (result) {
|
||||||
|
const inputs = parse_args(result);
|
||||||
|
|
||||||
|
console.log({ inputs });
|
||||||
|
|
||||||
|
for (let input of inputs) {
|
||||||
|
if (input[0] === 1) {
|
||||||
|
const geo = createGeometryFromEncodedData(input);
|
||||||
|
geometries = [geo];
|
||||||
|
console.log(geo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Scene geometry={geometries} />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
@ -6,15 +6,18 @@
|
|||||||
import * as templates from "$lib/graph-templates";
|
import * as templates from "$lib/graph-templates";
|
||||||
import type { Graph } from "@nodes/types";
|
import type { Graph } from "@nodes/types";
|
||||||
import { decode, encode } from "$lib/helpers/flat_tree";
|
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.decode = decode;
|
||||||
globalThis.encode = encode;
|
globalThis.encode = encode;
|
||||||
|
globalThis.df = decodeFloat;
|
||||||
|
globalThis.en = encodeFloat;
|
||||||
|
|
||||||
const nodeRegistry = new RemoteNodeRegistry("http://localhost:3001");
|
const nodeRegistry = new RemoteNodeRegistry("http://localhost:3001");
|
||||||
const runtimeExecutor = new MemoryRuntimeExecutor(nodeRegistry);
|
const runtimeExecutor = new MemoryRuntimeExecutor(nodeRegistry);
|
||||||
|
|
||||||
let res = "2";
|
let res: Int32Array;
|
||||||
let time = 0;
|
let time = 0;
|
||||||
|
|
||||||
let graph = localStorage.getItem("graph")
|
let graph = localStorage.getItem("graph")
|
||||||
@ -23,13 +26,7 @@
|
|||||||
|
|
||||||
function handleResult(event: CustomEvent<Graph>) {
|
function handleResult(event: CustomEvent<Graph>) {
|
||||||
let a = performance.now();
|
let a = performance.now();
|
||||||
let _res: any = runtimeExecutor.execute(event.detail);
|
res = 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;
|
|
||||||
}
|
|
||||||
time = performance.now() - a;
|
time = performance.now() - a;
|
||||||
console.log(res);
|
console.log(res);
|
||||||
}
|
}
|
||||||
@ -50,9 +47,7 @@
|
|||||||
</header>
|
</header>
|
||||||
<Grid.Row>
|
<Grid.Row>
|
||||||
<Grid.Cell>
|
<Grid.Cell>
|
||||||
result: {res}
|
<Viewer result={res} />
|
||||||
<br />
|
|
||||||
time: {time}ms
|
|
||||||
</Grid.Cell>
|
</Grid.Cell>
|
||||||
<Grid.Cell>
|
<Grid.Cell>
|
||||||
{#key graph}
|
{#key graph}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"input": {
|
"input": {
|
||||||
"type": "plant",
|
"type": "float",
|
||||||
"external": true
|
"external": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,48 @@
|
|||||||
use macros::include_definition_file;
|
use macros::include_definition_file;
|
||||||
use utils::evaluate_args;
|
use utils::{decode_float, encode_float};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use web_sys::console;
|
||||||
|
|
||||||
include_definition_file!("src/inputs.json");
|
include_definition_file!("src/inputs.json");
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn execute(args: &[i32]) -> Vec<i32> {
|
pub fn execute(input: &[i32]) -> Vec<i32> {
|
||||||
utils::set_panic_hook();
|
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]);
|
// let decoded = decode_float(result[0], result[1]);
|
||||||
|
|
||||||
// console::log_1(&format!("WASM: output: {:?}", decoded).into());
|
// console::log_1(&format!("WASM: output: {:?}", decoded).into());
|
||||||
|
@ -11,7 +11,7 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
|
|
||||||
let length = evaluate_args(args[0]);
|
let length = evaluate_args(args[0]);
|
||||||
let thickness = evaluate_args(args[1]);
|
let thickness = evaluate_args(args[1]);
|
||||||
let resolution = evaluate_args(args[2]);
|
let resolution = 32; //evaluate_args(args[2]);
|
||||||
|
|
||||||
console::log_1(
|
console::log_1(
|
||||||
&format!(
|
&format!(
|
||||||
@ -21,14 +21,20 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut result: Vec<i32> = Vec::with_capacity(args.len() + 3);
|
vec![
|
||||||
|
0, // opening bracket
|
||||||
result.push(0); // encoding the [ bracket
|
11, // opening bracket
|
||||||
result.push(2);
|
0, // type: plant
|
||||||
result.push(0); // adding the node-type, math: 0
|
0, // alpha: 0
|
||||||
result.extend_from_slice(&thickness);
|
0, // x
|
||||||
result.push(1);
|
0, // y
|
||||||
result.push(1); // closing bracket
|
0, // z
|
||||||
|
1, // thickness
|
||||||
result
|
0, // x
|
||||||
|
2, // y
|
||||||
|
0, // z
|
||||||
|
1, // thickness
|
||||||
|
1, // closing bracket
|
||||||
|
1, //closing bracket
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@ -11,3 +11,4 @@ wasm-bindgen = "0.2.92"
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
|
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||||
console_error_panic_hook = { version = "0.1.7", optional = true }
|
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||||
|
gl_matrix = "0.0.2"
|
||||||
|
@ -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 bits = f.to_bits();
|
||||||
let mantissa = (bits & 0x007FFFFF) as i32;
|
bits 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode_float(mantissa: i32, exponent: i32) -> f32 {
|
pub fn decode_float(bits: i32) -> f32 {
|
||||||
let sign_bit = ((mantissa >> 23) & 1) as u32; // Extract the sign bit
|
// Convert i32 to u32 safely, then use from_bits to get f32
|
||||||
let mantissa_bits = (mantissa & 0x007FFFFF) as u32;
|
let bits = bits as u32;
|
||||||
let exponent_bits = (exponent as u32 & 0xFF) << 23;
|
|
||||||
let bits = (sign_bit << 31) | exponent_bits | mantissa_bits; // Reconstruct all bits including sign
|
|
||||||
f32::from_bits(bits)
|
f32::from_bits(bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,20 +14,24 @@ pub fn decode_float(mantissa: i32, exponent: i32) -> f32 {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encode_decode() {
|
fn test_decode_float_simple() {
|
||||||
let original_floats = [
|
let test_values: [f32; 6] = [
|
||||||
0.0, 1.0, -1.0, 123.456, -123.456, 1e-10, -1e10, f32::MAX, f32::MIN,
|
0.0,
|
||||||
|
-0.0,
|
||||||
|
123.456,
|
||||||
|
-123.456,
|
||||||
|
std::f32::INFINITY,
|
||||||
|
std::f32::NEG_INFINITY,
|
||||||
];
|
];
|
||||||
for &original in &original_floats {
|
for &value in &test_values {
|
||||||
let (mantissa, exponent) = encode_float(original);
|
let encoded = encode_float(value);
|
||||||
let decoded = decode_float(mantissa, exponent);
|
let decoded = decode_float(encoded);
|
||||||
assert!(
|
assert_eq!(
|
||||||
(decoded - original).abs() < 1e-6,
|
decoded.to_bits(),
|
||||||
"Mismatch: original {} vs decoded {}",
|
value.to_bits(),
|
||||||
original,
|
"Failed for value {}",
|
||||||
decoded
|
value
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
packages/utils/src/geometry/extrude_path.rs
Normal file
2
packages/utils/src/geometry/extrude_path.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub fn extrude_path(path: &[i32]) {}
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
use crate::encoding;
|
use crate::encoding;
|
||||||
|
|
||||||
pub fn math_node(args: &[i32]) -> (i32, i32) {
|
pub fn math_node(args: &[i32]) -> i32 {
|
||||||
let math_type = args[0];
|
let math_type = args[0];
|
||||||
|
|
||||||
let a = encoding::decode_float(args[1], args[2]);
|
let a = encoding::decode_float(args[1]);
|
||||||
let b = encoding::decode_float(args[3], args[4]);
|
let b = encoding::decode_float(args[2]);
|
||||||
|
|
||||||
let result = match math_type {
|
let result = match math_type {
|
||||||
0 => a + b,
|
0 => a + b,
|
||||||
|
@ -57,12 +57,12 @@ pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
|
|||||||
out_args
|
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];
|
let node_type = input_args[0];
|
||||||
|
|
||||||
match node_type {
|
match node_type {
|
||||||
0 => crate::nodes::math_node(&input_args[1..]),
|
0 => crate::nodes::math_node(&input_args[1..]),
|
||||||
_ => (0, 0),
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ pub fn evaluate_args(input_args: &[i32]) -> Vec<i32> {
|
|||||||
|
|
||||||
if resolved.len() > 1 {
|
if resolved.len() > 1 {
|
||||||
let res = evaluate_node(&resolved);
|
let res = evaluate_node(&resolved);
|
||||||
vec![res.0, res.1]
|
vec![res]
|
||||||
} else {
|
} else {
|
||||||
resolved
|
resolved
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ mod tests {
|
|||||||
// the numbers are f32 floats encoded as two i32's
|
// the numbers are f32 floats encoded as two i32's
|
||||||
|
|
||||||
let result = evaluate_args(&input);
|
let result = evaluate_args(&input);
|
||||||
let decoded = decode_float(result[0], result[1]);
|
let decoded = decode_float(result[0]);
|
||||||
|
|
||||||
assert_eq!(decoded, 6.0);
|
assert_eq!(decoded, 6.0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user