// picogkffi sdf: Implicit SDF rendering via C-side callbacks.
// MoonBit's native backend does not support C->MoonBit callbacks cleanly,
// so the SDF implementations live in C (picogk_sdf.c) and are dispatched
// by type. This provides the same functionality as the Go FFI NewSDF callback.
///|
/// Render a gyroid sphere (gyroid TPMS clipped to a sphere) into the voxel field.
/// Uses max(abs(gyroid) - wall, sphere_sdf) composed SDF — same approach as PicoPie.
pub fn Voxels::render_gyroid_sphere(
self : Voxels,
bbox : BBox3,
radius : Double,
wall : Double,
k : Double,
) -> Unit {
mbt_render_gyroid_sphere(
get_instance(),
self.h,
Float::from_double(bbox.min.x),
Float::from_double(bbox.min.y),
Float::from_double(bbox.min.z),
Float::from_double(bbox.max.x),
Float::from_double(bbox.max.y),
Float::from_double(bbox.max.z),
Float::from_double(radius),
Float::from_double(wall),
Float::from_double(k),
)
}
///|
/// Render a gyroid sphere with x/y/z offset (for positioning in a scene).
pub fn Voxels::render_gyroid_sphere_offset(
self : Voxels,
bbox : BBox3,
radius : Double,
wall : Double,
k : Double,
ox : Double,
oy : Double,
oz : Double,
) -> Unit {
let offset = Vec3::new(ox, oy, oz)
mbt_render_gyroid_sphere_offset(
get_instance(),
self.h,
Float::from_double(bbox.min.x),
Float::from_double(bbox.min.y),
Float::from_double(bbox.min.z),
Float::from_double(bbox.max.x),
Float::from_double(bbox.max.y),
Float::from_double(bbox.max.z),
Float::from_double(radius),
Float::from_double(wall),
Float::from_double(k),
pack_vec3(offset),
)
}
///|
/// Render a gyroid genus (genus-2 surface intersected with gyroid) into the voxel field.
pub fn Voxels::render_gyroid_genus(
self : Voxels,
bbox : BBox3,
scale : Double,
gap : Double,
k : Double,
) -> Unit {
let sdf_params = FixedArray::make(12, 0L.to_byte())
write_float_le(sdf_params, 0, Float::from_double(scale))
write_float_le(sdf_params, 4, Float::from_double(gap))
write_float_le(sdf_params, 8, Float::from_double(k))
mbt_render_gyroid_genus(
get_instance(),
self.h,
Float::from_double(bbox.min.x),
Float::from_double(bbox.min.y),
Float::from_double(bbox.min.z),
Float::from_double(bbox.max.x),
Float::from_double(bbox.max.y),
Float::from_double(bbox.max.z),
sdf_params,
)
}
///|
/// Render a superellipsoid into the voxel field.
pub fn Voxels::render_superellipsoid(
self : Voxels,
bbox : BBox3,
a : Double,
b : Double,
c : Double,
e1 : Double,
e2 : Double,
) -> Unit {
let sdf_params = FixedArray::make(20, 0L.to_byte())
write_float_le(sdf_params, 0, Float::from_double(a))
write_float_le(sdf_params, 4, Float::from_double(b))
write_float_le(sdf_params, 8, Float::from_double(c))
write_float_le(sdf_params, 12, Float::from_double(e1))
write_float_le(sdf_params, 16, Float::from_double(e2))
mbt_render_superellipsoid(
get_instance(),
self.h,
Float::from_double(bbox.min.x),
Float::from_double(bbox.min.y),
Float::from_double(bbox.min.z),
Float::from_double(bbox.max.x),
Float::from_double(bbox.max.y),
Float::from_double(bbox.max.z),
sdf_params,
)
}
///|
/// Render a plain gyroid (TPMS shell) into the voxel field.
pub fn Voxels::render_gyroid(
self : Voxels,
bbox : BBox3,
wall : Double,
k : Double,
) -> Unit {
mbt_render_gyroid(
get_instance(),
self.h,
Float::from_double(bbox.min.x),
Float::from_double(bbox.min.y),
Float::from_double(bbox.min.z),
Float::from_double(bbox.max.x),
Float::from_double(bbox.max.y),
Float::from_double(bbox.max.z),
Float::from_double(wall),
Float::from_double(k),
)
}
///|
/// Intersect the voxel field with a gyroid sphere SDF (in-place).
pub fn Voxels::intersect_gyroid_sphere(
self : Voxels,
radius : Double,
wall : Double,
k : Double,
) -> Unit {
mbt_intersect_gyroid_sphere(
get_instance(),
self.h,
Float::from_double(radius),
Float::from_double(wall),
Float::from_double(k),
)
}
// --- C extern declarations ---
///|
extern "C" fn mbt_render_gyroid_sphere(
instance : Int64,
vox : Int64,
minX : Float,
minY : Float,
minZ : Float,
maxX : Float,
maxY : Float,
maxZ : Float,
radius : Float,
wall : Float,
k : Float,
) -> Unit = "mbt_render_gyroid_sphere"
///|
#borrow(offset)
extern "C" fn mbt_render_gyroid_sphere_offset(
instance : Int64,
vox : Int64,
minX : Float,
minY : Float,
minZ : Float,
maxX : Float,
maxY : Float,
maxZ : Float,
radius : Float,
wall : Float,
k : Float,
offset : FixedArray[Byte],
) -> Unit = "mbt_render_gyroid_sphere_offset"
///|
#borrow(sdf_params)
extern "C" fn mbt_render_gyroid_genus(
instance : Int64,
vox : Int64,
minX : Float,
minY : Float,
minZ : Float,
maxX : Float,
maxY : Float,
maxZ : Float,
sdf_params : FixedArray[Byte],
) -> Unit = "mbt_render_gyroid_genus"
///|
#borrow(sdf_params)
extern "C" fn mbt_render_superellipsoid(
instance : Int64,
vox : Int64,
minX : Float,
minY : Float,
minZ : Float,
maxX : Float,
maxY : Float,
maxZ : Float,
sdf_params : FixedArray[Byte],
) -> Unit = "mbt_render_superellipsoid"
///|
extern "C" fn mbt_render_gyroid(
instance : Int64,
vox : Int64,
minX : Float,
minY : Float,
minZ : Float,
maxX : Float,
maxY : Float,
maxZ : Float,
wall : Float,
k : Float,
) -> Unit = "mbt_render_gyroid"
///|
extern "C" fn mbt_intersect_gyroid_sphere(
instance : Int64,
vox : Int64,
radius : Float,
wall : Float,
k : Float,
) -> Unit = "mbt_intersect_gyroid_sphere"