use core::ffi::c_void;
pub struct Material {
pub(crate) ptr: *mut c_void,
}
unsafe impl Send for Material {}
unsafe impl Sync for Material {}
impl Clone for Material {
fn clone(&self) -> Self { unsafe { realitykit_sys::rk_retain(self.ptr) }; Material { ptr: self.ptr } }
}
impl Drop for Material {
fn drop(&mut self) { unsafe { realitykit_sys::rk_release(self.ptr) }; }
}
pub struct TextureResource {
pub(crate) ptr: *mut c_void,
}
unsafe impl Send for TextureResource {}
unsafe impl Sync for TextureResource {}
impl Clone for TextureResource {
fn clone(&self) -> Self { unsafe { realitykit_sys::rk_retain(self.ptr) }; TextureResource { ptr: self.ptr } }
}
impl Drop for TextureResource {
fn drop(&mut self) { unsafe { realitykit_sys::rk_release(self.ptr) }; }
}
impl TextureResource {
pub fn load(path: &str) -> Result<Self, String> {
let mut err = [0u8; 2048];
let p = unsafe { realitykit_sys::rk_texture_load(path.as_ptr(), path.len(), err.as_mut_ptr(), err.len()) };
if p.is_null() {
let n = err.iter().position(|&b| b == 0).unwrap_or(err.len());
Err(String::from_utf8_lossy(&err[..n]).into())
} else {
Ok(TextureResource { ptr: p })
}
}
pub fn from_rgba8(data: &[u8], width: u32, height: u32) -> Result<Self, String> {
assert_eq!(data.len(), (width * height * 4) as usize,
"data length must be width*height*4");
let mut err = [0u8; 2048];
let p = unsafe {
realitykit_sys::rk_texture_from_rgba8(
data.as_ptr(), data.len(),
width as i32, height as i32,
err.as_mut_ptr(), err.len(),
)
};
if p.is_null() {
let n = err.iter().position(|&b| b == 0).unwrap_or(err.len());
Err(String::from_utf8_lossy(&err[..n]).into())
} else {
Ok(TextureResource { ptr: p })
}
}
}
impl Material {
pub fn simple(r: f32, g: f32, b: f32) -> Self {
Material { ptr: unsafe { realitykit_sys::rk_material_simple(r, g, b, 0.5, false) } }
}
pub fn simple_full(r: f32, g: f32, b: f32, roughness: f32, metallic: bool) -> Self {
Material { ptr: unsafe { realitykit_sys::rk_material_simple(r, g, b, roughness, metallic) } }
}
pub fn simple_alpha(r: f32, g: f32, b: f32, a: f32, roughness: f32, metallic: bool) -> Self {
Material { ptr: unsafe { realitykit_sys::rk_material_simple_alpha(r, g, b, a, roughness, metallic) } }
}
pub fn unlit(r: f32, g: f32, b: f32) -> Self {
Material { ptr: unsafe { realitykit_sys::rk_material_unlit(r, g, b) } }
}
pub fn unlit_alpha(r: f32, g: f32, b: f32, a: f32) -> Self {
Material { ptr: unsafe { realitykit_sys::rk_material_unlit_alpha(r, g, b, a) } }
}
pub fn occlusion() -> Self {
Material { ptr: unsafe { realitykit_sys::rk_material_occlusion() } }
}
pub fn pbr() -> MaterialBuilder {
let ptr = unsafe { realitykit_sys::rk_material_pbr_new() };
MaterialBuilder { ptr }
}
}
pub struct MaterialBuilder {
pub(crate) ptr: *mut c_void,
}
unsafe impl Send for MaterialBuilder {}
unsafe impl Sync for MaterialBuilder {}
impl Drop for MaterialBuilder {
fn drop(&mut self) { unsafe { realitykit_sys::rk_release(self.ptr) }; }
}
impl MaterialBuilder {
pub fn base_color(self, r: f32, g: f32, b: f32, a: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_base_color(self.ptr, r, g, b, a) }; self
}
pub fn roughness(self, v: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_roughness(self.ptr, v) }; self
}
pub fn metallic(self, v: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_metallic(self.ptr, v) }; self
}
pub fn emissive(self, r: f32, g: f32, b: f32, intensity: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_emissive(self.ptr, r, g, b, intensity) }; self
}
pub fn opacity(self, v: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_opacity(self.ptr, v) }; self
}
pub fn clearcoat(self, cc: f32, roughness: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_clearcoat(self.ptr, cc, roughness) }; self
}
pub fn sheen(self, r: f32, g: f32, b: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_sheen(self.ptr, r, g, b) }; self
}
pub fn specular(self, v: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_specular(self.ptr, v) }; self
}
pub fn anisotropy(self, v: f32) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_anisotropy(self.ptr, v) }; self
}
pub fn base_color_texture(self, tex: &TextureResource) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_base_color_texture(self.ptr, tex.ptr) }; self
}
pub fn normal_texture(self, tex: &TextureResource) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_normal_texture(self.ptr, tex.ptr) }; self
}
pub fn roughness_texture(self, tex: &TextureResource) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_roughness_texture(self.ptr, tex.ptr) }; self
}
pub fn metallic_texture(self, tex: &TextureResource) -> Self {
unsafe { realitykit_sys::rk_material_pbr_set_metallic_texture(self.ptr, tex.ptr) }; self
}
pub fn build(self) -> Material {
unsafe { realitykit_sys::rk_retain(self.ptr) };
Material { ptr: self.ptr }
}
}
impl From<MaterialBuilder> for Material {
fn from(b: MaterialBuilder) -> Material { b.build() }
}
impl Material {
pub fn video(url: &str) -> Result<Self, String> {
let mut err = [0u8; 2048];
let p = unsafe {
realitykit_sys::rk_material_video(url.as_ptr(), url.len(), err.as_mut_ptr(), err.len())
};
if p.is_null() {
let n = err.iter().position(|&b| b == 0).unwrap_or(err.len());
Err(String::from_utf8_lossy(&err[..n]).into())
} else {
Ok(Material { ptr: p })
}
}
pub fn video_play(&self) { unsafe { realitykit_sys::rk_material_video_play(self.ptr) } }
pub fn video_pause(&self) { unsafe { realitykit_sys::rk_material_video_pause(self.ptr) } }
pub fn portal() -> Self {
Material { ptr: unsafe { realitykit_sys::rk_material_portal_new() } }
}
pub fn shader_graph_from_file(material_name: &str, file_path: &str) -> Result<Self, String> {
let mut err = [0u8; 2048];
let p = unsafe {
realitykit_sys::rk_material_shader_graph_from_file(
material_name.as_ptr(), material_name.len(),
file_path.as_ptr(), file_path.len(),
err.as_mut_ptr(), err.len(),
)
};
if p.is_null() {
let n = err.iter().position(|&b| b == 0).unwrap_or(err.len());
Err(String::from_utf8_lossy(&err[..n]).into())
} else {
Ok(Material { ptr: p })
}
}
}