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