Files
nodarium/nodes/max/plantarium/instance/src/lib.rs
T
release-bot 4f48a519a9
🚀 Lint & Test & Deploy / release (pull_request) Successful in 4m9s
feat(nodes): add rotation to instance node
2026-02-09 22:16:20 +01:00

87 lines
2.5 KiB
Rust

use glam::{Mat4, Quat, Vec3};
use nodarium_macros::{nodarium_execute, nodarium_definition_file};
use nodarium_utils::{
concat_args, evaluate_float, evaluate_int,
geometry::{create_instance_data, wrap_geometry_data, wrap_instance_data, wrap_path},
split_args,
};
nodarium_definition_file!("src/input.json");
#[nodarium_execute]
pub fn execute(input: &[i32]) -> Vec<i32> {
let args = split_args(input);
let mut inputs = split_args(args[0]);
let mut geo_data = args[1].to_vec();
let geo = wrap_geometry_data(&mut geo_data);
let mut transforms: Vec<Mat4> = Vec::new();
// Find max depth
let mut max_depth = 0;
for path_data in inputs.iter() {
if path_data[2] != 0 {
continue;
}
max_depth = max_depth.max(path_data[3]);
}
let rotation = evaluate_float(args[5]);
let depth = evaluate_int(args[6]);
for path_data in inputs.iter() {
if path_data[3] < (max_depth - depth + 1) {
continue;
}
let amount = evaluate_int(args[2]);
let lowest_instance = evaluate_float(args[3]);
let highest_instance = evaluate_float(args[4]);
let path = wrap_path(path_data);
for i in 0..amount {
let alpha = lowest_instance
+ (i as f32 / (amount - 1) as f32) * (highest_instance - lowest_instance);
let point = path.get_point_at(alpha);
let tangent = path.get_direction_at(alpha);
let size = point[3] + 0.01;
let axis_rotation = Quat::from_axis_angle(
Vec3::from_slice(&tangent).normalize(),
i as f32 * rotation,
);
let path_rotation = Quat::from_rotation_arc(Vec3::Y, Vec3::from_slice(&tangent).normalize());
let rotation = path_rotation * axis_rotation;
let transform = Mat4::from_scale_rotation_translation(
Vec3::new(size, size, size),
rotation,
Vec3::from_slice(&point),
);
transforms.push(transform);
}
}
let mut instance_data = create_instance_data(
geo.positions.len() / 3,
geo.faces.len() / 3,
transforms.len(),
);
let mut instances = wrap_instance_data(&mut instance_data);
instances.set_geometry(geo);
for (i, transform) in transforms.iter().enumerate() {
instances.set_transformation_matrix(i, &transform.to_cols_array());
}
inputs.push(&instance_data);
concat_args(inputs)
}