use core::ffi::c_void;
pub struct AnimationController {
pub(crate) ptr: *mut c_void,
}
unsafe impl Send for AnimationController {}
unsafe impl Sync for AnimationController {}
impl Drop for AnimationController {
fn drop(&mut self) { unsafe { realitykit_sys::rk_release(self.ptr) }; }
}
impl AnimationController {
pub fn pause(&self) { unsafe { realitykit_sys::rk_animation_controller_pause(self.ptr) }; }
pub fn resume(&self) { unsafe { realitykit_sys::rk_animation_controller_resume(self.ptr) }; }
pub fn stop(&self) { unsafe { realitykit_sys::rk_animation_controller_stop(self.ptr) }; }
pub fn is_playing(&self) -> bool { unsafe { realitykit_sys::rk_animation_controller_is_playing(self.ptr) } }
pub fn is_paused(&self) -> bool { unsafe { realitykit_sys::rk_animation_controller_is_paused(self.ptr) } }
pub fn is_complete(&self) -> bool { !self.is_playing() && !self.is_paused() }
}
#[repr(i32)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum TimingFunction {
Linear = 0,
EaseIn = 1,
EaseOut = 2,
EaseInOut = 3,
}
#[repr(i32)]
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub enum AnimationRepeatMode {
#[default]
None = 0,
Repeat = 1,
Cumulative = 2,
AutoReverse = 3,
}
pub struct AnimationResource {
pub(crate) ptr: *mut c_void,
}
unsafe impl Send for AnimationResource {}
unsafe impl Sync for AnimationResource {}
impl Clone for AnimationResource {
fn clone(&self) -> Self { unsafe { realitykit_sys::rk_retain(self.ptr) }; AnimationResource { ptr: self.ptr } }
}
impl Drop for AnimationResource {
fn drop(&mut self) { unsafe { realitykit_sys::rk_release(self.ptr) }; }
}
pub struct AnimationDefinition {
pub(crate) ptr: *mut c_void,
}
unsafe impl Send for AnimationDefinition {}
unsafe impl Sync for AnimationDefinition {}
impl Clone for AnimationDefinition {
fn clone(&self) -> Self { unsafe { realitykit_sys::rk_retain(self.ptr) }; AnimationDefinition { ptr: self.ptr } }
}
impl Drop for AnimationDefinition {
fn drop(&mut self) { unsafe { realitykit_sys::rk_release(self.ptr) }; }
}
impl AnimationDefinition {
pub fn build(self) -> Result<AnimationResource, String> {
let mut err = [0u8; 2048];
let p = unsafe {
realitykit_sys::rk_animation_resource_from_def(self.ptr, 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(AnimationResource { ptr: p })
}
}
pub fn orbit(
axis: [f32; 3],
rotation_count: f32,
clockwise: bool,
duration: f64,
repeat_mode: AnimationRepeatMode,
is_additive: bool,
) -> Self {
AnimationDefinition {
ptr: unsafe {
realitykit_sys::rk_animdef_orbit(
axis[0], axis[1], axis[2],
rotation_count, clockwise, false,
duration, repeat_mode as i32, is_additive,
)
},
}
}
pub fn from_to_transform(
from: [f32; 10],
to: [f32; 10],
duration: f64,
timing: TimingFunction,
repeat_mode: AnimationRepeatMode,
is_additive: bool,
) -> Self {
AnimationDefinition {
ptr: unsafe {
realitykit_sys::rk_animdef_from_to_transform(
from[0], from[1], from[2],
from[3], from[4], from[5], from[6],
from[7], from[8], from[9],
to[0], to[1], to[2],
to[3], to[4], to[5], to[6],
to[7], to[8], to[9],
duration, timing as i32, repeat_mode as i32, is_additive,
)
},
}
}
}
impl AnimationResource {
pub fn group(defs: &[AnimationDefinition], speed: f32) -> Result<Self, String> {
let handles: Vec<*mut c_void> = defs.iter().map(|d| d.ptr).collect();
let mut err = [0u8; 2048];
let p = unsafe {
realitykit_sys::rk_animation_resource_group(
handles.as_ptr() as *const _,
handles.len(),
speed,
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(AnimationResource { ptr: p })
}
}
}