feat: yyyess, got extrude_path working
This commit is contained in:
parent
3af7ebb672
commit
6ea4afa012
@ -6,13 +6,12 @@
|
|||||||
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 { onMount } from "svelte";
|
|
||||||
|
|
||||||
export let geometries: BufferGeometry[];
|
export let geometries: BufferGeometry[];
|
||||||
export let lines: Vector3[][];
|
export let lines: Vector3[][];
|
||||||
|
|
||||||
let camera: PerspectiveCamera;
|
export let camera: PerspectiveCamera;
|
||||||
let controls: OrbitControlsType;
|
export let controls: OrbitControlsType;
|
||||||
|
|
||||||
const cameraTransform = localStore<{ camera: number[]; target: number[] }>(
|
const cameraTransform = localStore<{ camera: number[]; target: number[] }>(
|
||||||
"nodes.camera.transform",
|
"nodes.camera.transform",
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Canvas } from "@threlte/core";
|
import { Canvas } from "@threlte/core";
|
||||||
import Scene from "./Scene.svelte";
|
import Scene from "./Scene.svelte";
|
||||||
import { BufferGeometry, Float32BufferAttribute, Vector3 } from "three";
|
import {
|
||||||
|
BufferGeometry,
|
||||||
|
Float32BufferAttribute,
|
||||||
|
PerspectiveCamera,
|
||||||
|
Vector3,
|
||||||
|
} from "three";
|
||||||
import { decodeFloat } from "@nodes/utils";
|
import { decodeFloat } from "@nodes/utils";
|
||||||
|
import type { OrbitControls } from "three/examples/jsm/Addons.js";
|
||||||
|
|
||||||
export let result: Int32Array;
|
export let result: Int32Array;
|
||||||
|
|
||||||
|
export let camera: PerspectiveCamera;
|
||||||
|
export let controls: OrbitControls;
|
||||||
|
export let center: Vector3;
|
||||||
|
|
||||||
let geometries: BufferGeometry[] = [];
|
let geometries: BufferGeometry[] = [];
|
||||||
let lines: Vector3[][] = [];
|
let lines: Vector3[][] = [];
|
||||||
|
|
||||||
@ -92,8 +102,6 @@
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
globalThis.parse_args = parse_args;
|
|
||||||
|
|
||||||
function createLineGeometryFromEncodedData(encodedData: Int32Array) {
|
function createLineGeometryFromEncodedData(encodedData: Int32Array) {
|
||||||
const positions: Vector3[] = [];
|
const positions: Vector3[] = [];
|
||||||
|
|
||||||
@ -120,19 +128,25 @@
|
|||||||
})
|
})
|
||||||
.filter(Boolean) as Vector3[][];
|
.filter(Boolean) as Vector3[][];
|
||||||
|
|
||||||
|
center = new Vector3();
|
||||||
|
|
||||||
geometries = inputs
|
geometries = inputs
|
||||||
.map((input) => {
|
.map((input) => {
|
||||||
if (input[0] === 1) {
|
if (input[0] === 1) {
|
||||||
const geo = createGeometryFromEncodedData(input);
|
const geo = createGeometryFromEncodedData(input);
|
||||||
|
geo?.computeBoundingSphere();
|
||||||
|
if (geo.boundingSphere) {
|
||||||
|
center.add(geo.boundingSphere.center);
|
||||||
|
}
|
||||||
return geo;
|
return geo;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(Boolean) as BufferGeometry[];
|
.filter(Boolean) as BufferGeometry[];
|
||||||
|
|
||||||
console.log(lines);
|
center = center.divideScalar(geometries.length);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Scene {geometries} {lines} />
|
<Scene bind:camera bind:controls {geometries} {lines} />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
@ -34,6 +34,11 @@ export const AppSettingTypes = {
|
|||||||
label: "Show Grid",
|
label: "Show Grid",
|
||||||
value: true,
|
value: true,
|
||||||
},
|
},
|
||||||
|
centerCamera: {
|
||||||
|
type: "boolean",
|
||||||
|
label: "Center Camera",
|
||||||
|
value: true
|
||||||
|
},
|
||||||
nodeInterface: {
|
nodeInterface: {
|
||||||
__title: "Node Interface",
|
__title: "Node Interface",
|
||||||
showNodeGrid: {
|
showNodeGrid: {
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
import type { GraphManager } from "$lib/graph-interface/graph-manager";
|
import type { GraphManager } from "$lib/graph-interface/graph-manager";
|
||||||
import { setContext } from "svelte";
|
import { setContext } from "svelte";
|
||||||
import { decodeNestedArray, encodeNestedArray } from "@nodes/utils";
|
import { decodeNestedArray, encodeNestedArray } from "@nodes/utils";
|
||||||
|
import type { PerspectiveCamera, Vector3 } from "three";
|
||||||
|
import type { OrbitControls } from "three/examples/jsm/Addons.js";
|
||||||
|
import GraphView from "$lib/graph-interface/graph/GraphView.svelte";
|
||||||
|
|
||||||
const nodeRegistry = new RemoteNodeRegistry("");
|
const nodeRegistry = new RemoteNodeRegistry("");
|
||||||
const runtimeExecutor = new MemoryRuntimeExecutor(nodeRegistry);
|
const runtimeExecutor = new MemoryRuntimeExecutor(nodeRegistry);
|
||||||
@ -23,6 +26,9 @@
|
|||||||
globalThis.encode = encodeNestedArray;
|
globalThis.encode = encodeNestedArray;
|
||||||
|
|
||||||
let res: Int32Array;
|
let res: Int32Array;
|
||||||
|
let viewerCamera: PerspectiveCamera;
|
||||||
|
let viewerControls: OrbitControls;
|
||||||
|
let viewerCenter: Vector3;
|
||||||
|
|
||||||
let graph = localStorage.getItem("graph")
|
let graph = localStorage.getItem("graph")
|
||||||
? JSON.parse(localStorage.getItem("graph")!)
|
? JSON.parse(localStorage.getItem("graph")!)
|
||||||
@ -38,6 +44,11 @@
|
|||||||
|
|
||||||
function handleResult(event: CustomEvent<Graph>) {
|
function handleResult(event: CustomEvent<Graph>) {
|
||||||
res = runtimeExecutor.execute(event.detail, get(settings?.graph?.settings));
|
res = runtimeExecutor.execute(event.detail, get(settings?.graph?.settings));
|
||||||
|
|
||||||
|
if ($AppSettings.centerCamera && viewerCamera && viewerCenter) {
|
||||||
|
viewerControls.target.copy(viewerCenter);
|
||||||
|
viewerControls.update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSave(event: CustomEvent<Graph>) {
|
function handleSave(event: CustomEvent<Graph>) {
|
||||||
@ -117,7 +128,12 @@
|
|||||||
<header></header>
|
<header></header>
|
||||||
<Grid.Row>
|
<Grid.Row>
|
||||||
<Grid.Cell>
|
<Grid.Cell>
|
||||||
<Viewer result={res} />
|
<Viewer
|
||||||
|
bind:controls={viewerControls}
|
||||||
|
bind:center={viewerCenter}
|
||||||
|
bind:camera={viewerCamera}
|
||||||
|
result={res}
|
||||||
|
/>
|
||||||
</Grid.Cell>
|
</Grid.Cell>
|
||||||
<Grid.Cell>
|
<Grid.Cell>
|
||||||
{#key graph}
|
{#key graph}
|
||||||
|
@ -19,6 +19,12 @@
|
|||||||
},
|
},
|
||||||
"seed": {
|
"seed": {
|
||||||
"type": "seed"
|
"type": "seed"
|
||||||
|
},
|
||||||
|
"fixBottom": {
|
||||||
|
"type": "float",
|
||||||
|
"hidden": true,
|
||||||
|
"min": 0,
|
||||||
|
"max": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
set_panic_hook();
|
set_panic_hook();
|
||||||
|
|
||||||
let args = get_args(input);
|
let args = get_args(input);
|
||||||
|
|
||||||
let plants = get_args(args[0]);
|
let plants = get_args(args[0]);
|
||||||
let scale = evaluate_float(args[1]);
|
let scale = evaluate_float(args[1]);
|
||||||
let strength = evaluate_float(args[2]);
|
let strength = evaluate_float(args[2]);
|
||||||
@ -32,8 +33,8 @@ pub fn execute(input: &[i32]) -> Vec<i32> {
|
|||||||
let a = i as f64 / (points - 1) as f64;
|
let a = i as f64 / (points - 1) as f64;
|
||||||
let px = Vector2::new(0.0, a * scale as f64);
|
let px = Vector2::new(0.0, a * scale as f64);
|
||||||
let pz = Vector2::new(a * scale as f64, 0.0);
|
let pz = Vector2::new(a * scale as f64, 0.0);
|
||||||
let nx = open_simplex_2d(px, &hasher) as f32 * strength * 0.1;
|
let nx = open_simplex_2d(px, &hasher) as f32 * strength * 0.1 * a as f32;
|
||||||
let nz = open_simplex_2d(pz, &hasher) as f32 * strength * 0.1;
|
let nz = open_simplex_2d(pz, &hasher) as f32 * strength * 0.1 * a as f32;
|
||||||
plant[3 + i * 4] = encode_float(decode_float(plant[3 + i * 4]) + nx);
|
plant[3 + i * 4] = encode_float(decode_float(plant[3 + i * 4]) + nx);
|
||||||
plant[5 + i * 4] = encode_float(decode_float(plant[5 + i * 4]) + nz);
|
plant[5 + i * 4] = encode_float(decode_float(plant[5 + i * 4]) + nz);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
use glam::{Mat4, Vec3};
|
|
||||||
use macros::include_definition_file;
|
use macros::include_definition_file;
|
||||||
use utils::{
|
use utils::{concat_args, evaluate_int, geometry::extrude_path, get_args, log};
|
||||||
concat_args, evaluate_int,
|
|
||||||
geometry::{extrude_path, transform_geometry},
|
|
||||||
get_args, log,
|
|
||||||
};
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
include_definition_file!("src/inputs.json");
|
include_definition_file!("src/inputs.json");
|
||||||
|
@ -86,6 +86,8 @@ pub struct DefaultOptions {
|
|||||||
pub setting: Option<String>,
|
pub setting: Option<String>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub label: Option<serde_json::Value>, // To handle both String and false
|
pub label: Option<serde_json::Value>, // To handle both String and false
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub hidden: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
use crate::log;
|
||||||
|
|
||||||
use super::{create_geometry_data, wrap_geometry_data};
|
use super::{create_geometry_data, wrap_geometry_data};
|
||||||
use glam::{Mat4, Quat, Vec3};
|
use glam::{Mat4, Vec3};
|
||||||
|
|
||||||
fn create_circle(res: usize) -> Vec<f32> {
|
fn create_circle(res: usize) -> Vec<f32> {
|
||||||
let angle = (2.0 * std::f32::consts::PI) / res as f32;
|
let angle = (2.0 * std::f32::consts::PI) / res as f32;
|
||||||
@ -11,7 +13,6 @@ fn create_circle(res: usize) -> Vec<f32> {
|
|||||||
circle
|
circle
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec<i32> {
|
pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec<i32> {
|
||||||
let point_amount = input_path.len() / 4;
|
let point_amount = input_path.len() / 4;
|
||||||
let face_amount = (point_amount - 1) * res_x * 2;
|
let face_amount = (point_amount - 1) * res_x * 2;
|
||||||
@ -33,51 +34,63 @@ pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec<i32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..point_amount {
|
for i in 0..point_amount {
|
||||||
|
|
||||||
let index_offset = i * res_x * 6;
|
let index_offset = i * res_x * 6;
|
||||||
let position_offset = i * res_x;
|
let position_offset = i * res_x;
|
||||||
|
|
||||||
let point = Vec3::from_slice(&path[i*4..i*4+3]);
|
let pos = Vec3::new(path[i * 4], path[i * 4 + 1], path[i * 4 + 2]);
|
||||||
let thickness = path[i*4+3];
|
let thickness = path[i * 4 + 3];
|
||||||
let next_point = if i == point_amount - 1 { point } else { Vec3::from_slice(&path[(i+1)*4..(i+1)*4+3]) };
|
|
||||||
let prev_point = if i == 0 { point } else { Vec3::from_slice(&path[(i-1)*4..(i-1)*4+3]) };
|
|
||||||
|
|
||||||
let mut v = if i == 0 {
|
// Get direction of the current segment
|
||||||
point - next_point
|
let segment_dir = (if i == 0 {
|
||||||
|
Vec3::new(
|
||||||
|
pos[0] - path[i * 4 + 4],
|
||||||
|
pos[1] - path[i * 4 + 5],
|
||||||
|
pos[2] - path[i * 4 + 6],
|
||||||
|
)
|
||||||
} else if i == point_amount - 1 {
|
} else if i == point_amount - 1 {
|
||||||
prev_point - point
|
Vec3::new(
|
||||||
|
path[i * 4 - 4] - pos[0],
|
||||||
|
path[i * 4 - 3] - pos[1],
|
||||||
|
path[i * 4 - 2] - pos[2],
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
prev_point - next_point
|
Vec3::new(
|
||||||
};
|
path[i * 4 - 4] - path[i * 4 + 4],
|
||||||
v = v.normalize();
|
path[i * 4 - 3] - path[i * 4 + 5],
|
||||||
|
path[i * 4 - 2] - path[i * 4 + 6],
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.normalize();
|
||||||
|
|
||||||
let n = Vec3::new(0.0, -1.0, 0.0); // Assuming 'n' is the up vector or similar
|
// In our case the up vector is always the Y axis
|
||||||
let axis = n.cross(v);
|
let up_vector = Vec3::NEG_Y;
|
||||||
let angle = n.dot(v).acos();
|
|
||||||
|
|
||||||
let quat = Quat::from_axis_angle(axis, angle).normalize();
|
let binormal = up_vector.cross(segment_dir);
|
||||||
let mat = Mat4::IDENTITY * Mat4::from_quat(quat);
|
|
||||||
|
let rotation_angle = up_vector.dot(segment_dir).acos();
|
||||||
|
|
||||||
|
let rotation_matrix = Mat4::from_axis_angle(binormal, rotation_angle);
|
||||||
|
|
||||||
for j in 0..res_x {
|
for j in 0..res_x {
|
||||||
|
|
||||||
if i < point_amount - 1 {
|
if i < point_amount - 1 {
|
||||||
|
|
||||||
let i_index_offset = index_offset + j * 6;
|
let i_index_offset = index_offset + j * 6;
|
||||||
let i_position_offset = position_offset + j;
|
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 {
|
if j == res_x - 1 {
|
||||||
indices[i_index_offset ] = (i_position_offset + 1) as i32;
|
indices[i_index_offset] = (i_position_offset + 1) as i32;
|
||||||
indices[i_index_offset + 1] = (i_position_offset + 1 - res_x) as i32;
|
indices[i_index_offset + 1] = (i_position_offset + 1 - res_x) as i32;
|
||||||
indices[i_index_offset + 2] = (i_position_offset) as i32;
|
indices[i_index_offset + 2] = (i_position_offset) as i32;
|
||||||
|
|
||||||
indices[i_index_offset + 3] = (i_position_offset) as i32;
|
indices[i_index_offset + 3] = (i_position_offset) as i32;
|
||||||
indices[i_index_offset + 4] = (i_position_offset + res_x) as i32;
|
indices[i_index_offset + 4] = (i_position_offset + res_x) as i32;
|
||||||
indices[i_index_offset + 5] = (i_position_offset + 1) as i32;
|
indices[i_index_offset + 5] = (i_position_offset + 1) as i32;
|
||||||
} else {
|
} else {
|
||||||
indices[i_index_offset ] = (i_position_offset + res_x + 1) as i32;
|
indices[i_index_offset] = (i_position_offset + res_x + 1) as i32;
|
||||||
indices[i_index_offset + 1] = (i_position_offset + 1) as i32;
|
indices[i_index_offset + 1] = (i_position_offset + 1) as i32;
|
||||||
indices[i_index_offset + 2] = (i_position_offset) as i32;
|
indices[i_index_offset + 2] = (i_position_offset) as i32;
|
||||||
|
|
||||||
indices[i_index_offset + 3] = (i_position_offset) as i32;
|
indices[i_index_offset + 3] = (i_position_offset) as i32;
|
||||||
indices[i_index_offset + 4] = (i_position_offset + res_x) as i32;
|
indices[i_index_offset + 4] = (i_position_offset + res_x) as i32;
|
||||||
indices[i_index_offset + 5] = (i_position_offset + res_x + 1) as i32;
|
indices[i_index_offset + 5] = (i_position_offset + res_x + 1) as i32;
|
||||||
@ -87,24 +100,21 @@ pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec<i32> {
|
|||||||
// construct the points
|
// construct the points
|
||||||
let idx = i * res_x * 3 + j * 3;
|
let idx = i * res_x * 3 + j * 3;
|
||||||
|
|
||||||
let circle_x = circle[j * 2 ] * thickness;
|
let circle_x = circle[j * 2] * thickness;
|
||||||
let circle_y = circle[j * 2 + 1] * thickness;
|
let circle_z = circle[j * 2 + 1] * thickness;
|
||||||
|
|
||||||
let _pt = Vec3::new(
|
let point = rotation_matrix.transform_point3(Vec3::new(circle_x, 0.0, circle_z)) + pos;
|
||||||
point[0] + circle_x,
|
let normal = rotation_matrix
|
||||||
point[1],
|
.transform_vector3(Vec3::new(circle_x, 0.0, circle_z))
|
||||||
point[2] + circle_y,
|
.normalize();
|
||||||
);
|
|
||||||
|
|
||||||
let pt = Mat4::transform_vector3(&mat, _pt) + point;
|
normals[idx] = normal[0];
|
||||||
|
normals[idx + 1] = normal[1];
|
||||||
|
normals[idx + 2] = normal[2];
|
||||||
|
|
||||||
normals[idx ] = circle_x;
|
positions[idx] = point[0];
|
||||||
normals[idx + 1] = 0.0;
|
positions[idx + 1] = point[1];
|
||||||
normals[idx + 2] = circle_y;
|
positions[idx + 2] = point[2];
|
||||||
|
|
||||||
positions[idx ] = pt[0];
|
|
||||||
positions[idx + 1] = pt[1];
|
|
||||||
positions[idx + 2] = pt[2];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use utils::get_args;
|
use utils::get_args;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn main() {
|
fn test_split_args(){
|
||||||
let inputs = vec![
|
let inputs = vec![
|
||||||
vec![0, 1, 0, 4, 1056964608, 1065353216, 1056964608, 1, 4, 1080872141, 1054951342, 32, 1, 1 ],
|
vec![0, 1, 0, 4, 1056964608, 1065353216, 1056964608, 1, 4, 1080872141, 1054951342, 32, 1, 1 ],
|
||||||
vec![0, 4, 1056964608, 1065353216, 1056964608, 1, 4],
|
vec![0, 4, 1056964608, 1065353216, 1056964608, 1, 4],
|
||||||
@ -14,5 +14,6 @@ fn main() {
|
|||||||
for input in inputs {
|
for input in inputs {
|
||||||
println!("RESULT: {:?}", get_args(&input));
|
println!("RESULT: {:?}", get_args(&input));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
@ -192,15 +192,6 @@ mod tests {
|
|||||||
1053609165, 54,
|
1053609165, 54,
|
||||||
];
|
];
|
||||||
|
|
||||||
// this should be the output
|
|
||||||
/* [
|
|
||||||
[ 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 ],
|
|
||||||
1086324736,
|
|
||||||
1053609165,
|
|
||||||
54
|
|
||||||
] */
|
|
||||||
|
|
||||||
|
|
||||||
let args = get_args(&input);
|
let args = get_args(&input);
|
||||||
println!("{:?}", args[0]);
|
println!("{:?}", args[0]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user