From b75503d7a31a481079991ccc343438f8f329d690 Mon Sep 17 00:00:00 2001 From: Riccardo Zaglia Date: Sat, 14 Oct 2023 00:22:28 +0800 Subject: [PATCH] feat(server): :sparkles: Define draft libalvr API --- Cargo.lock | 1 + alvr/server/Cargo.toml | 1 + alvr/server/src/c_api.rs | 267 +++++++++++++++++++++++++++++++++++++++ alvr/server/src/lib.rs | 1 + 4 files changed, 270 insertions(+) create mode 100644 alvr/server/src/c_api.rs diff --git a/Cargo.lock b/Cargo.lock index 45a3979522..485aa1f66a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,6 +348,7 @@ dependencies = [ "alvr_server_io", "alvr_session", "alvr_sockets", + "ash", "bincode", "bindgen 0.66.1", "bytes", diff --git a/alvr/server/Cargo.toml b/alvr/server/Cargo.toml index 066cf0e5b3..2fa3831e9d 100644 --- a/alvr/server/Cargo.toml +++ b/alvr/server/Cargo.toml @@ -22,6 +22,7 @@ alvr_server_io.workspace = true alvr_session.workspace = true alvr_sockets.workspace = true +ash = "0.37" bincode = "1" bytes = "1" chrono = "0.4" diff --git a/alvr/server/src/c_api.rs b/alvr/server/src/c_api.rs new file mode 100644 index 0000000000..e78a106107 --- /dev/null +++ b/alvr/server/src/c_api.rs @@ -0,0 +1,267 @@ +use ash::vk; +use std::{ + ffi::{c_char, CStr}, + time::Instant, +}; + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrFov { + /// Negative, radians + pub left: f32, + /// Positive, radians + pub right: f32, + /// Positive, radians + pub up: f32, + /// Negative, radians + pub down: f32, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrQuat { + pub x: f32, + pub y: f32, + pub z: f32, + pub w: f32, +} +impl Default for AlvrQuat { + fn default() -> Self { + Self { + x: 0.0, + y: 0.0, + z: 0.0, + w: 1.0, + } + } +} + +#[repr(C)] +#[derive(Clone, Copy, Default)] +pub struct AlvrPose { + orientation: AlvrQuat, + position: [f32; 3], +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrSpaceRelation { + pub pose: AlvrPose, + pub linear_velocity: [f32; 3], + pub angular_velocity: [f32; 3], + pub has_velocity: bool, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrJoint { + relation: AlvrSpaceRelation, + radius: f32, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrJointSet { + values: [AlvrJoint; 26], + global_hand_relation: AlvrSpaceRelation, + is_active: bool, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub union AlvrInputValue { + pub bool_: bool, + pub float_: f32, +} + +// the profile is implied +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrInput { + pub id: u64, + pub value: AlvrInputValue, +} + +#[repr(u8)] +#[derive(Clone, Copy)] +pub enum AlvrOutput { + Haptics { + frequency: f32, + amplitude: f32, + duration_ns: u64, + }, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrBatteryValue { + pub device_id: u64, + /// range [0, 1] + pub value: f32, +} + +#[repr(C)] +pub enum AlvrEvent { + Battery(AlvrBatteryValue), + Bounds([f32; 2]), + Restart, + Shutdown, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrTargetConfig { + target_width: u32, + target_height: u32, +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct AlvrDeviceConfig { + device_id: u64, + interaction_profile_id: u64, +} + +// Get ALVR server time. The libalvr user should provide timestamps in the provided time frame of +// reference in the following functions +#[no_mangle] +pub unsafe extern "C" fn alvr_get_time_ns() -> u64 { + Instant::now().elapsed().as_nanos() as u64 +} + +// The libalvr user is responsible of interpreting values and calling functions using +// device/input/output identifiers obtained using this function +#[no_mangle] +pub unsafe extern "C" fn alvr_path_to_id(path_string: *const c_char) -> u64 { + alvr_common::hash_string(CStr::from_ptr(path_string).to_str().unwrap()) +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_initialize(out_target_config: *mut AlvrTargetConfig) { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent) -> bool { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_shutdown() { + todo!() +} + +// Device API: + +// Use the two-call pattern to first get the array length then the array data. +#[no_mangle] +pub unsafe extern "C" fn alvr_get_devices(out_device_configs: *mut AlvrDeviceConfig) -> u64 { + todo!() +} + +// After this call, previous button and tracking data is discarded +#[no_mangle] +pub unsafe extern "C" fn alvr_update_inputs(device_id: u64) { + todo!() +} + +// Use the two-call pattern to first get the array length then the array data. +// Data is updated after a call to alvr_update_inputs. +#[no_mangle] +pub unsafe extern "C" fn alvr_get_inputs( + device_id: u64, + out_inputs_arr: *mut AlvrInput, + out_timestamp_ns: u64, +) -> u64 { + todo!() +} + +// pose_id is something like /user/hand/left/input/grip/pose +#[no_mangle] +pub unsafe extern "C" fn alvr_get_tracked_pose( + pose_id: u64, + timestamp_ns: u64, + out_relation: *mut AlvrSpaceRelation, +) { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_get_hand_tracking( + device_id: u64, + timestamp_ns: u64, + out_joint_set: *mut AlvrJointSet, +) { + todo!() +} + +// Currently only haptics is supported +#[no_mangle] +pub unsafe extern "C" fn alvr_set_output(output_id: u64, value: *const AlvrOutput) { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_view_poses( + out_head_relation: *mut AlvrSpaceRelation, + out_fov_arr: *mut AlvrFov, // 2 elements + out_relative_pose_arr: *mut AlvrPose, // 2 elements +) { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_destroy_device(device_id: u64) { + todo!() +} + +// Compositor target API: + +// This should reflect the client current framerate +#[no_mangle] +pub unsafe extern "C" fn alvr_get_framerate() -> f32 { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_pre_vulkan() { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_post_vulkan() { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_create_vk_target_swapchain( + width: u32, + height: u32, + color_format: vk::Format, + color_space: vk::ColorSpaceKHR, + image_usage: vk::ImageUsageFlags, + present_mode: vk::PresentModeKHR, + image_count: u64, +) { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_acquire_image(out_swapchain_index: u64) -> vk::Result { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_present( + queue: vk::Queue, + swapchain_index: u64, + timeline_semaphore_value: u64, + timestamp_ns: u64, +) -> vk::Result { + todo!() +} + +#[no_mangle] +pub unsafe extern "C" fn alvr_destroy_vk_target_swapchain() { + todo!() +} diff --git a/alvr/server/src/lib.rs b/alvr/server/src/lib.rs index bc3f00475d..b970ad559e 100644 --- a/alvr/server/src/lib.rs +++ b/alvr/server/src/lib.rs @@ -1,4 +1,5 @@ mod bitrate; +mod c_api; mod connection; mod face_tracking; mod hand_gestures;