feat: add vec3 to stem
This commit is contained in:
@ -12,5 +12,4 @@ web-sys = { version = "0.3.69", features = ["console"] }
|
||||
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"
|
||||
glam = "0.27.0"
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::create_empty_geometry;
|
||||
use super::{create_geometry_data, wrap_geometry_data};
|
||||
use glam::{Mat4, Quat, Vec3};
|
||||
|
||||
fn create_circle(res: usize) -> Vec<f32> {
|
||||
@ -19,22 +19,19 @@ pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec<i32> {
|
||||
|
||||
let circle = create_circle(res_x);
|
||||
|
||||
let mut geometry = create_empty_geometry(vertices_amount, face_amount);
|
||||
let mut geometry_data = create_geometry_data(vertices_amount, face_amount);
|
||||
|
||||
let geometry = wrap_geometry_data(&mut geometry_data);
|
||||
|
||||
let normals = geometry.normals;
|
||||
let positions = geometry.positions;
|
||||
let indices = geometry.faces;
|
||||
|
||||
let (_header,rest) = geometry.split_at_mut(5);
|
||||
let (indices, rest) = rest.split_at_mut(face_amount*3);
|
||||
let (_positions, _normals) = rest.split_at_mut(vertices_amount*3);
|
||||
let positions: &mut [f32];
|
||||
let normals: &mut [f32];
|
||||
let path: &[f32];
|
||||
unsafe {
|
||||
path = std::slice::from_raw_parts(input_path.as_ptr() as *const f32, input_path.len());
|
||||
positions = std::slice::from_raw_parts_mut(_positions.as_mut_ptr() as *mut f32, _positions.len());
|
||||
normals = std::slice::from_raw_parts_mut(_normals.as_mut_ptr() as *mut f32, _normals.len());
|
||||
}
|
||||
|
||||
normals[0] = 0.0;
|
||||
|
||||
for i in 0..point_amount {
|
||||
|
||||
let index_offset = i * res_x * 6;
|
||||
@ -109,5 +106,5 @@ pub fn extrude_path(input_path: &[i32], res_x: usize) -> Vec<i32> {
|
||||
}
|
||||
}
|
||||
|
||||
geometry
|
||||
geometry_data
|
||||
}
|
||||
|
74
packages/utils/src/geometry/geometry.rs
Normal file
74
packages/utils/src/geometry/geometry.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use crate::log;
|
||||
|
||||
pub struct GeometryData<'a> {
|
||||
pub positions: &'a mut [f32], // View into `data`
|
||||
pub normals: &'a mut [f32], // View into `data`
|
||||
pub faces: &'a mut [i32], // View into `data`
|
||||
}
|
||||
|
||||
pub fn create_geometry_data(vertex_amount: usize, face_amount: usize) -> Vec<i32> {
|
||||
let amount = 3 // definition (type, vertex_amount, face_amount)
|
||||
+ 4 // opening and closing brackets
|
||||
+ vertex_amount * 3 // positions
|
||||
+ vertex_amount * 3 // normals
|
||||
+ face_amount * 3; // faces
|
||||
|
||||
let mut geo = vec![0; amount];
|
||||
|
||||
geo[0] = 0; // opening bracket
|
||||
geo[1] = amount as i32 - 2; // opening bracket
|
||||
geo[2] = 1; // type: geometry
|
||||
geo[3] = vertex_amount as i32;
|
||||
geo[4] = face_amount as i32;
|
||||
geo[amount - 2] = 1; // closing bracket
|
||||
geo[amount - 1] = 1; // closing bracket
|
||||
|
||||
geo
|
||||
}
|
||||
|
||||
pub fn wrap_geometry_data(geometry: &mut [i32]) -> GeometryData {
|
||||
// Basic validity checks
|
||||
assert!(
|
||||
geometry.len() > 5,
|
||||
"Geometry vector does not contain enough data for a header."
|
||||
);
|
||||
|
||||
// Split at after header
|
||||
let (header, rest) = geometry.split_at_mut(5);
|
||||
|
||||
let vertices_amount = header[3] as usize;
|
||||
let face_amount = header[4] as usize;
|
||||
let total_floats = vertices_amount * 3 * 2;
|
||||
|
||||
let (faces, rest) = rest.split_at_mut(face_amount * 3);
|
||||
let (positions_slice, rest) = rest.split_at_mut(vertices_amount * 3);
|
||||
let (normals_slice, _) = rest.split_at_mut(vertices_amount * 3);
|
||||
|
||||
log!(
|
||||
"Vertices: {}, normals: {}, Total floats: {}",
|
||||
positions_slice.len(),
|
||||
normals_slice.len(),
|
||||
total_floats
|
||||
);
|
||||
|
||||
assert!(
|
||||
positions_slice.len() + normals_slice.len() == total_floats,
|
||||
"Slices do not match the expected sizes."
|
||||
);
|
||||
|
||||
let positions: &mut [f32] = unsafe {
|
||||
std::slice::from_raw_parts_mut(
|
||||
positions_slice.as_mut_ptr() as *mut f32,
|
||||
positions_slice.len(),
|
||||
)
|
||||
};
|
||||
let normals: &mut [f32] = unsafe {
|
||||
std::slice::from_raw_parts_mut(normals_slice.as_mut_ptr() as *mut f32, normals_slice.len())
|
||||
};
|
||||
|
||||
GeometryData {
|
||||
positions,
|
||||
normals,
|
||||
faces,
|
||||
}
|
||||
}
|
@ -1,33 +1,9 @@
|
||||
mod calculate_normals;
|
||||
mod extrude_path;
|
||||
mod geometry;
|
||||
mod transform;
|
||||
|
||||
pub use calculate_normals::*;
|
||||
pub use extrude_path::*;
|
||||
|
||||
use crate::log;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn create_empty_geometry(vertex_amount: usize, face_amount: usize) -> Vec<i32> {
|
||||
log!(
|
||||
"create_empty_geometry: vertex_amount: {}, face_amount: {}",
|
||||
vertex_amount,
|
||||
face_amount
|
||||
);
|
||||
|
||||
let amount =
|
||||
3 // definition (type, vertex_amount, face_amount)
|
||||
+ 4 // opening and closing brackets
|
||||
+ vertex_amount * 3 // positions
|
||||
+ vertex_amount * 3 // normals
|
||||
+ face_amount * 3; // faces
|
||||
|
||||
let mut vec: Vec<i32> = vec![0; amount];
|
||||
vec[0] = 0; // opening bracket
|
||||
vec[1] = amount as i32 - 2; // opening bracket
|
||||
vec[2] = 1; // type: geometry
|
||||
vec[3] = vertex_amount as i32;
|
||||
vec[4] = face_amount as i32;
|
||||
vec[amount - 2] = 1; // closing bracket
|
||||
vec[amount - 1] = 1; // closing bracket
|
||||
vec
|
||||
}
|
||||
pub use geometry::*;
|
||||
pub use transform::*;
|
||||
|
25
packages/utils/src/geometry/transform.rs
Normal file
25
packages/utils/src/geometry/transform.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use glam::{Mat4, Vec3};
|
||||
|
||||
pub fn transform_geometry(mut geometry: Vec<i32>, matrix: Mat4) -> Vec<i32> {
|
||||
let (_header, rest) = geometry.split_at_mut(5);
|
||||
|
||||
let vertices_amount = _header[3] as usize;
|
||||
let face_amount = _header[4] as usize;
|
||||
|
||||
let (_indices, rest) = rest.split_at_mut(face_amount * 3);
|
||||
let (_positions, _normals) = rest.split_at_mut(vertices_amount * 3);
|
||||
let positions: &mut [f32];
|
||||
unsafe {
|
||||
positions =
|
||||
std::slice::from_raw_parts_mut(_positions.as_mut_ptr() as *mut f32, _positions.len());
|
||||
}
|
||||
|
||||
for i in 0..vertices_amount {
|
||||
let pos = Mat4::transform_point3(&matrix, Vec3::from_slice(&positions[i * 3..i * 3 + 3]));
|
||||
positions[i * 3] = pos.x;
|
||||
positions[i * 3 + 1] = pos.y;
|
||||
positions[i * 3 + 2] = pos.z;
|
||||
}
|
||||
|
||||
geometry
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
use crate::decode_float;
|
||||
|
||||
pub fn get_args(args: &[i32]) -> Vec<&[i32]> {
|
||||
let mut idx: usize = 0;
|
||||
let mut depth = -1;
|
||||
@ -105,13 +107,29 @@ pub fn evaluate_node(input_args: &[i32]) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn evaluate_args(input_args: &[i32]) -> Vec<i32> {
|
||||
if input_args.len() == 1 {
|
||||
return input_args.to_vec();
|
||||
}
|
||||
pub fn evaluate_vec3(input_args: &[i32]) -> Vec<f32> {
|
||||
let args = get_args(input_args);
|
||||
|
||||
if input_args.len() == 4 && input_args[0] == 0 && input_args[1] == 3 {
|
||||
return vec![input_args[2], input_args[3]];
|
||||
assert!(
|
||||
args.len() == 3,
|
||||
"Failed to evaluate Vec3 - Expected 3 arguments, got {}",
|
||||
args.len()
|
||||
);
|
||||
|
||||
let x = evaluate_float(args[0]);
|
||||
let y = evaluate_float(args[1]);
|
||||
let z = evaluate_float(args[2]);
|
||||
|
||||
vec![x, y, z]
|
||||
}
|
||||
|
||||
pub fn evaluate_float(arg: &[i32]) -> f32 {
|
||||
decode_float(evaluate_arg(arg))
|
||||
}
|
||||
|
||||
pub fn evaluate_arg(input_args: &[i32]) -> i32 {
|
||||
if input_args.len() == 1 {
|
||||
return input_args.to_vec()[0];
|
||||
}
|
||||
|
||||
let args = get_args(input_args);
|
||||
@ -125,22 +143,20 @@ pub fn evaluate_args(input_args: &[i32]) -> Vec<i32> {
|
||||
resolved.push(arg[2]);
|
||||
resolved.push(arg[3]);
|
||||
} else {
|
||||
resolved.push(evaluate_args(arg)[0]);
|
||||
resolved.push(evaluate_arg(arg));
|
||||
}
|
||||
}
|
||||
|
||||
if resolved.len() > 1 {
|
||||
let res = evaluate_node(&resolved);
|
||||
vec![res]
|
||||
evaluate_node(&resolved)
|
||||
} else {
|
||||
resolved
|
||||
resolved[0]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use crate::encoding::decode_float;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
@ -152,10 +168,9 @@ mod tests {
|
||||
// and another math node that adds 2 to that result
|
||||
// the numbers are f32 floats encoded as two i32's
|
||||
|
||||
let result = evaluate_args(&input);
|
||||
let decoded = decode_float(result[0]);
|
||||
let result = evaluate_float(&input);
|
||||
|
||||
assert_eq!(decoded, 6.0);
|
||||
assert_eq!(result, 6.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Reference in New Issue
Block a user