use super::guard::ffi_guard;
use super::registry::{get_node, register_node};
use super::types::*;
use std::slice;
#[no_mangle]
pub extern "C" fn alice_sdf_translate(node: SdfHandle, x: f32, y: f32, z: f32) -> SdfHandle {
ffi_guard(SDF_HANDLE_NULL, || {
let sdf_node = match get_node(node) {
Some(n) => n,
None => return SDF_HANDLE_NULL,
};
let new_node = (*sdf_node).clone().translate(x, y, z);
register_node(new_node)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_rotate(
node: SdfHandle,
qx: f32,
qy: f32,
qz: f32,
qw: f32,
) -> SdfHandle {
ffi_guard(SDF_HANDLE_NULL, || {
let sdf_node = match get_node(node) {
Some(n) => n,
None => return SDF_HANDLE_NULL,
};
let quat = glam::Quat::from_xyzw(qx, qy, qz, qw).normalize();
let new_node = (*sdf_node).clone().rotate(quat);
register_node(new_node)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_rotate_euler(node: SdfHandle, x: f32, y: f32, z: f32) -> SdfHandle {
ffi_guard(SDF_HANDLE_NULL, || {
let sdf_node = match get_node(node) {
Some(n) => n,
None => return SDF_HANDLE_NULL,
};
let new_node = (*sdf_node).clone().rotate_euler(x, y, z);
register_node(new_node)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_scale(node: SdfHandle, factor: f32) -> SdfHandle {
ffi_guard(SDF_HANDLE_NULL, || {
let sdf_node = match get_node(node) {
Some(n) => n,
None => return SDF_HANDLE_NULL,
};
let new_node = (*sdf_node).clone().scale(factor);
register_node(new_node)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_scale_xyz(node: SdfHandle, x: f32, y: f32, z: f32) -> SdfHandle {
ffi_guard(SDF_HANDLE_NULL, || {
let sdf_node = match get_node(node) {
Some(n) => n,
None => return SDF_HANDLE_NULL,
};
let new_node = (*sdf_node).clone().scale_xyz(x, y, z);
register_node(new_node)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_projective_transform(
node: SdfHandle,
inv_matrix: *const f32,
lipschitz_bound: f32,
) -> SdfHandle {
ffi_guard(SDF_HANDLE_NULL, || {
if inv_matrix.is_null() {
return SDF_HANDLE_NULL;
}
let sdf_node = match get_node(node) {
Some(n) => n,
None => return SDF_HANDLE_NULL,
};
let matrix = unsafe { slice::from_raw_parts(inv_matrix, 16) };
let matrix_array: [f32; 16] = match matrix.try_into() {
Ok(m) => m,
Err(_) => return SDF_HANDLE_NULL,
};
let new_node = (*sdf_node)
.clone()
.projective_transform(matrix_array, lipschitz_bound);
register_node(new_node)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_lattice_deform(
node: SdfHandle,
control_points: *const f32,
cp_count: u32,
nx: u32,
ny: u32,
nz: u32,
bbox_min: *const f32,
bbox_max: *const f32,
) -> SdfHandle {
ffi_guard(SDF_HANDLE_NULL, || {
if control_points.is_null() || bbox_min.is_null() || bbox_max.is_null() {
return SDF_HANDLE_NULL;
}
let sdf_node = match get_node(node) {
Some(n) => n,
None => return SDF_HANDLE_NULL,
};
let expected_count = (nx * ny * nz) as usize * 3;
if cp_count as usize * 3 != expected_count {
return SDF_HANDLE_NULL;
}
let cp_slice = unsafe { slice::from_raw_parts(control_points, cp_count as usize * 3) };
let min_slice = unsafe { slice::from_raw_parts(bbox_min, 3) };
let max_slice = unsafe { slice::from_raw_parts(bbox_max, 3) };
let control_pts: Vec<glam::Vec3> = cp_slice
.chunks_exact(3)
.map(|c| glam::Vec3::new(c[0], c[1], c[2]))
.collect();
let bbox_min_vec = glam::Vec3::new(min_slice[0], min_slice[1], min_slice[2]);
let bbox_max_vec = glam::Vec3::new(max_slice[0], max_slice[1], max_slice[2]);
let new_node =
(*sdf_node)
.clone()
.lattice_deform(control_pts, nx, ny, nz, bbox_min_vec, bbox_max_vec);
register_node(new_node)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_skinning(
node: SdfHandle,
bones: *const f32,
bone_count: u32,
) -> SdfHandle {
ffi_guard(SDF_HANDLE_NULL, || {
if bones.is_null() {
return SDF_HANDLE_NULL;
}
let sdf_node = match get_node(node) {
Some(n) => n,
None => return SDF_HANDLE_NULL,
};
use crate::transforms::skinning::BoneTransform;
let bone_slice = unsafe { slice::from_raw_parts(bones, bone_count as usize * 33) };
let mut bone_transforms = Vec::new();
for chunk in bone_slice.chunks_exact(33) {
let inv_bind: [f32; 16] = chunk[0..16].try_into().unwrap();
let current: [f32; 16] = chunk[16..32].try_into().unwrap();
let weight = chunk[32];
bone_transforms.push(BoneTransform {
inv_bind_pose: inv_bind,
current_pose: current,
weight,
});
}
let new_node = (*sdf_node).clone().sdf_skinning(bone_transforms);
register_node(new_node)
})
}