#[diplomat::bridge]
pub mod ffi {
use super::super::schematic::ffi::Schematic;
use super::super::shared::ffi::NucleationError;
use base64::Engine;
use diplomat_runtime::DiplomatWrite;
use std::fmt::Write;
#[diplomat::opaque_mut]
pub struct RenderConfig(pub(crate) crate::rendering::RenderConfig);
impl RenderConfig {
pub fn create(width: u32, height: u32) -> Box<RenderConfig> {
Box::new(RenderConfig(crate::rendering::RenderConfig {
width,
height,
..crate::rendering::RenderConfig::default()
}))
}
pub fn set_yaw(&mut self, yaw: f32) {
self.0.yaw = yaw;
}
pub fn set_pitch(&mut self, pitch: f32) {
self.0.pitch = pitch;
}
pub fn set_zoom(&mut self, zoom: f32) {
self.0.zoom = zoom;
}
pub fn set_sphere_fit(&mut self, sphere_fit: bool) {
self.0.sphere_fit = sphere_fit;
}
pub fn set_fov(&mut self, fov: f32) {
self.0.fov = fov;
}
pub fn set_background(&mut self, r: f32, g: f32, b: f32, a: f32) {
self.0.background = Some([r, g, b, a]);
}
pub fn clear_background(&mut self) {
self.0.background = None;
}
pub fn set_orthographic(&mut self, orthographic: bool) {
self.0.projection = if orthographic {
crate::rendering::Projection::Orthographic
} else {
crate::rendering::Projection::Perspective
};
}
pub fn set_isometric(&mut self) {
let w = self.0.width;
let h = self.0.height;
let mut iso = crate::rendering::RenderConfig::isometric();
iso.width = w;
iso.height = h;
self.0 = iso;
}
}
#[diplomat::opaque]
pub struct Renderer;
impl Renderer {
fn mesh(
schematic: &Schematic,
pack_zip: &[u8],
) -> Result<crate::meshing::MeshOutput, NucleationError> {
let pack = crate::meshing::ResourcePackSource::from_bytes(pack_zip)
.map_err(|_| NucleationError::Parse)?;
let mesh_config = crate::meshing::MeshConfig::default();
schematic
.0
.to_mesh(&pack, &mesh_config)
.map_err(|_| NucleationError::Mesh)
}
pub fn render_pixels_b64(
schematic: &Schematic,
pack_zip: &[u8],
config: &RenderConfig,
out: &mut DiplomatWrite,
) -> Result<(), NucleationError> {
let mesh = Self::mesh(schematic, pack_zip)?;
let pixels = crate::rendering::render_meshes(&[mesh], &config.0, None)
.map_err(|_| NucleationError::Render)?;
let _ = write!(
out,
"{}",
base64::engine::general_purpose::STANDARD.encode(&pixels)
);
Ok(())
}
pub fn render_png_b64(
schematic: &Schematic,
pack_zip: &[u8],
config: &RenderConfig,
out: &mut DiplomatWrite,
) -> Result<(), NucleationError> {
let mesh = Self::mesh(schematic, pack_zip)?;
let png = crate::rendering::render_meshes_png(&[mesh], &config.0, None)
.map_err(|_| NucleationError::Render)?;
let _ = write!(
out,
"{}",
base64::engine::general_purpose::STANDARD.encode(&png)
);
Ok(())
}
pub fn render_to_file(
schematic: &Schematic,
pack_zip: &[u8],
config: &RenderConfig,
path: &DiplomatStr,
) -> Result<(), NucleationError> {
let path = std::str::from_utf8(path).map_err(|_| NucleationError::InvalidArgument)?;
let pack = crate::meshing::ResourcePackSource::from_bytes(pack_zip)
.map_err(|_| NucleationError::Parse)?;
schematic
.0
.render_to_file(&pack, path, &config.0)
.map_err(|_| NucleationError::Render)
}
}
}