LeapRS is an unofficial safe wrapper for LeapC, the Leap Motion C API. It uses the generated binding provided by leap-sys.
This is an API for accessing Leap Motion/Ultraleap hand tracking device. It works on Linux and Windows.
Warning: This library is not complete and not fully tested. Moreover, it includes unsafe code to interact with the C API. It should be treated with caution in its current state.
The goal of LeapRS is to cover entirely LeapC in a safe way. It is intended to be as close as possible to the original C library. As such, it's fairly low level and carries most of the difficulties of using LeapC.
It is not intended to provide any full featured framework such as having a worker thread and provide an async API. It is intended to be usable to create such framework though.
The current coverage includes most of the necessary functions to interact with a Leap Motion device in a single or a multi device environment. The interpolation and distortion methods are not fully translated and not fully tested.
The allocation API is not exposed.
Add leaprs
to the current project: cargo add leaprs
You also need to install the LeapMotion Tracking Software.
This library was created for the version named Geminy
(5.6.1).
If you install this software in a custom path, you need to define the
environment variable LEAPSDK_LIB_PATH
(default: C:\Program Files\Ultraleap\LeapSDK\lib\x64
on Windows and
/usr/share/doc/ultraleap-hand-tracking-service
on Linux).
At runtime, the application requires the LeapC.dll file to be available. The
easiest way to do it during development is to add its folder to the PATH
environment variable. For distribution, refer to the SDK licensing.
The main entrypoint is [Connection::create]. For most of the basic usage of hand tracking, you will have to use [Connection::poll] and retrieve the underlying event with [ConnectionMessage::event]. The various possible events are described in the [EventRef] enum, including [EventRef::Tracking] containing the hand positions.
use leaprs::*;
let mut c = Connection::create(ConnectionConfig::default()).unwrap();
c.open().unwrap();
for _ in 0..10 {
if let Ok(msg) = c.poll(1000) {
match msg.event() {
EventRef::Tracking(e) => println!("{} hand(s)", e.hands().len()),
_ => {}
}
}
}
Most of the types in leaprs
are wrappers with no data around the underlying LeapC
structures. These wrappers expose both:
- Handy methods for accessing the data, for example [TrackingEventRef::hands] lists the visible hands
- Direct access to the underlying data via the
Deref
trait, for example [HandRef] gives direct access to [leap_sys::LEAP_HAND::confidence]:hand_ref.confidence
When both members are available (.hands
and .hands()
), the function is the
recommended one to get a safe wrapper. The field access can be useful to
circumvent a leaprs
limitation.
leaprs
includes opt-in glam
and nalgebra
integrations.
They are two popular linear algebra library. Both are commonly used, and these features can help integrating with ecosystem using these crates.
glam
is used by Bevy
, and nalgebra
is used by Fyrox
.
cargo build --features glam
use leaprs::*;
use glam::{Vec3, Quat};
let mut c = Connection::create(ConnectionConfig::default()).unwrap();
c.open().unwrap();
for _ in 0..10 {
if let Ok(msg) = c.poll(1000) {
match msg.event() {
EventRef::Tracking(e) => {
for hand in e.hands() {
let position: Vec3 = hand.palm().position().into();
let orientation: Quat = hand.palm().orientation().into();
}
},
_ => {}
}
}
}
cargo build --features nalgebra
use leaprs::*;
use nalgebra::{Vector3, UnitQuaternion};
let mut c = Connection::create(ConnectionConfig::default()).unwrap();
c.open().unwrap();
for _ in 0..10 {
if let Ok(msg) = c.poll(1000) {
match msg.event() {
EventRef::Tracking(e) => {
for hand in e.hands() {
let position: Vector3<f32> = hand.palm().position().into();
let orientation: UnitQuaternion<f32> = hand.palm().orientation().into();
}
},
_ => {}
}
}
}
Disabling the geminy
feature enables building application for the previous SDK
generation (Orion). In Cargo.toml:
[dependencies = { version = "*", default-features = false }]
You also need to point the LEAPSDK_LIB_PATH
to a SDK with the Orion version.
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
This license only covers the leaprs
wrapper, and not the underlying LeapC
library.
The enum safety is provided through num_enum.
The bitflags are wrapped using bitflags.
Most struct are simple wrappers around their C counter-part. Most of the time, the C struct is the only member of the wrapper, except when external allocation is needed (when providing a pre-allocated array to LeapC). Accessors are then exposing all the functions and members associated with these structs in a consistent way.
The test require to have the Leap software up and running, and to have a device connected.