reorg again
This commit is contained in:
parent
ae4719f6ab
commit
692606229a
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,3 +8,5 @@ Cargo.lock
|
|||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
bazel-*
|
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"ostream": "cpp"
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,2 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = ["libodm"]
|
||||||
"libleap-sys",
|
|
||||||
# "libleap",
|
|
||||||
# "libodm",
|
|
||||||
# "snapscan",
|
|
||||||
]
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "libleap"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Evan Pratten <ewpratten@gmail.com>"]
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
leap-sys = "0.1.1"
|
|
||||||
num = "0.4"
|
|
||||||
num-derive = "0.3"
|
|
||||||
num-traits = "0.2"
|
|
@ -1,72 +0,0 @@
|
|||||||
use leap_sys::eLeapRS;
|
|
||||||
|
|
||||||
#[derive(FromPrimitive, Debug)]
|
|
||||||
pub enum LeapError {
|
|
||||||
/// The operation completed successfully.
|
|
||||||
Success = 0,
|
|
||||||
/// An undetermined error has occurred.
|
|
||||||
/// This is usually the result of an abnormal operating condition in LeapC,
|
|
||||||
/// the Leap Motion service, or the host computer itself.
|
|
||||||
UnknownError = -503250944,
|
|
||||||
/// An invalid argument was specified.
|
|
||||||
InvalidArgument = -503250943,
|
|
||||||
/// Insufficient resources existed to complete the request.
|
|
||||||
InsufficientResources = -503250942,
|
|
||||||
/// The specified buffer was not large enough to complete the request.
|
|
||||||
InsufficientBuffer = -503250941,
|
|
||||||
/// The requested operation has timed out.
|
|
||||||
Timeout = -503250940,
|
|
||||||
/// The operation is invalid because there is no current connection.
|
|
||||||
NotConnected = -503250939,
|
|
||||||
/// The operation is invalid because the connection is not complete.
|
|
||||||
HandshakeIncomplete = -503250938,
|
|
||||||
/// The specified buffer size is too large.
|
|
||||||
BufferSizeOverflow = -503250937,
|
|
||||||
/// A communications protocol error occurred.
|
|
||||||
ProtocolError = -503250936,
|
|
||||||
/// The server incorrectly specified zero as a client ID.
|
|
||||||
InvalidClientID = -503250935,
|
|
||||||
/// The connection to the service was unexpectedly closed while reading or writing a message.
|
|
||||||
/// The server may have terminated.
|
|
||||||
UnexpectedClosed = -503250934,
|
|
||||||
/// The specified request token does not appear to be valid
|
|
||||||
///
|
|
||||||
/// Provided that the token value which identifies the request itself was, at one point, valid, this
|
|
||||||
/// error condition occurs when the request to which the token refers has already been satisfied or
|
|
||||||
/// is currently being satisfied.
|
|
||||||
UnknownImageFrameRequest = -503250933,
|
|
||||||
/// The specified frame ID is not valid or is no longer valid
|
|
||||||
///
|
|
||||||
/// Provided that frame ID was, at one point, valid, this error condition occurs when the identifier
|
|
||||||
/// refers to a frame that occurred further in the past than is currently recorded in the rolling
|
|
||||||
/// frame window.
|
|
||||||
UnknownTrackingFrameID = -503250932,
|
|
||||||
/// The specified timestamp references a future point in time
|
|
||||||
///
|
|
||||||
/// The related routine can only operate on time points having occurred in the past, and the
|
|
||||||
/// provided timestamp occurs in the future.
|
|
||||||
RoutineIsNotSeer = -503250931,
|
|
||||||
/// The specified timestamp references a point too far in the past
|
|
||||||
///
|
|
||||||
/// The related routine can only operate on time points occurring within its immediate record of
|
|
||||||
/// the past.
|
|
||||||
TimestampTooEarly = -503250930,
|
|
||||||
/// LeapPollConnection is called concurrently.
|
|
||||||
ConcurrentPoll = -503250929,
|
|
||||||
/// A connection to the Leap Motion service could not be established.
|
|
||||||
NotAvailable = -419364862,
|
|
||||||
/// The requested operation can only be performed while the device is sending data.
|
|
||||||
NotStreaming = -419364860,
|
|
||||||
/// The specified device could not be opened. It is possible that the device identifier
|
|
||||||
/// is invalid, or that the device has been disconnected since being enumerated.
|
|
||||||
CannotOpenDevice = -419364859,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<eLeapRS> for LeapError {
|
|
||||||
fn from(error: eLeapRS) -> Self {
|
|
||||||
match num::FromPrimitive::from_i32(error) {
|
|
||||||
Some(e) => e,
|
|
||||||
None => Self::UnknownError,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
//! Wrappers for LeapMotion device events
|
|
||||||
|
|
||||||
use leap_sys::{
|
|
||||||
LEAP_CONFIG_CHANGE_EVENT, LEAP_CONFIG_RESPONSE_EVENT, LEAP_CONNECTION_EVENT,
|
|
||||||
LEAP_CONNECTION_LOST_EVENT, LEAP_CONNECTION_MESSAGE, LEAP_DEVICE_EVENT,
|
|
||||||
LEAP_DEVICE_FAILURE_EVENT, LEAP_HEAD_POSE_EVENT, LEAP_IMAGE_EVENT, LEAP_LOG_EVENT,
|
|
||||||
LEAP_LOG_EVENTS, LEAP_POINT_MAPPING_CHANGE_EVENT, LEAP_POLICY_EVENT, LEAP_TRACKING_EVENT,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Event {
|
|
||||||
Invalid,
|
|
||||||
Connection(*const LEAP_CONNECTION_EVENT),
|
|
||||||
ConnectionLost(*const LEAP_CONNECTION_LOST_EVENT),
|
|
||||||
Device(*const LEAP_DEVICE_EVENT),
|
|
||||||
DeviceLost(*const LEAP_DEVICE_EVENT),
|
|
||||||
DeviceFailure(*const LEAP_DEVICE_FAILURE_EVENT),
|
|
||||||
Tracking(*const LEAP_TRACKING_EVENT),
|
|
||||||
ImageComplete,
|
|
||||||
ImageRequestError,
|
|
||||||
LogEvent(*const LEAP_LOG_EVENT),
|
|
||||||
Policy(*const LEAP_POLICY_EVENT),
|
|
||||||
ConfigChange(*const LEAP_CONFIG_CHANGE_EVENT),
|
|
||||||
ConfigResponse(*const LEAP_CONFIG_RESPONSE_EVENT),
|
|
||||||
Image(*const LEAP_IMAGE_EVENT),
|
|
||||||
PointMappingChange(*const LEAP_POINT_MAPPING_CHANGE_EVENT),
|
|
||||||
LogEvents(*const LEAP_LOG_EVENTS),
|
|
||||||
HeadPose(*const LEAP_HEAD_POSE_EVENT),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<LEAP_CONNECTION_MESSAGE> for Event {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn from(message: LEAP_CONNECTION_MESSAGE) -> Self {
|
|
||||||
unsafe {
|
|
||||||
match message.type_ {
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_Connection => {
|
|
||||||
Self::Connection(message.__bindgen_anon_1.connection_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_ConnectionLost => {
|
|
||||||
Self::ConnectionLost(message.__bindgen_anon_1.connection_lost_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_Device => {
|
|
||||||
Self::Device(message.__bindgen_anon_1.device_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_DeviceLost => {
|
|
||||||
Self::DeviceLost(message.__bindgen_anon_1.device_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_DeviceFailure => {
|
|
||||||
Self::DeviceFailure(message.__bindgen_anon_1.device_failure_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_Tracking => {
|
|
||||||
Self::Tracking(message.__bindgen_anon_1.tracking_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_ImageComplete => Self::ImageComplete,
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_ImageRequestError => {
|
|
||||||
Self::ImageRequestError
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_LogEvent => {
|
|
||||||
Self::LogEvent(message.__bindgen_anon_1.log_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_Policy => {
|
|
||||||
Self::Policy(message.__bindgen_anon_1.policy_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_ConfigChange => {
|
|
||||||
Self::ConfigChange(message.__bindgen_anon_1.config_change_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_ConfigResponse => {
|
|
||||||
Self::ConfigResponse(message.__bindgen_anon_1.config_response_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_Image => {
|
|
||||||
Self::Image(message.__bindgen_anon_1.image_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_PointMappingChange => {
|
|
||||||
Self::PointMappingChange(message.__bindgen_anon_1.point_mapping_change_event)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_LogEvents => {
|
|
||||||
Self::LogEvents(message.__bindgen_anon_1.log_events)
|
|
||||||
}
|
|
||||||
leap_sys::_eLeapEventType_eLeapEventType_HeadPose => {
|
|
||||||
Self::HeadPose(message.__bindgen_anon_1.head_pose_event)
|
|
||||||
}
|
|
||||||
_ => Self::Invalid,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,140 +0,0 @@
|
|||||||
#[macro_use]
|
|
||||||
extern crate num_derive;
|
|
||||||
|
|
||||||
use std::{sync::{
|
|
||||||
mpsc::{self, Sender},
|
|
||||||
Arc,
|
|
||||||
}, thread::Thread, time::{Duration, SystemTime}};
|
|
||||||
|
|
||||||
use error::LeapError;
|
|
||||||
use event::Event;
|
|
||||||
use leap_sys::{
|
|
||||||
_eLeapRS_eLeapRS_Success,
|
|
||||||
LEAP_CONNECTION, LEAP_CONNECTION_MESSAGE,LeapCreateConnection, LeapOpenConnection, LeapPollConnection
|
|
||||||
};
|
|
||||||
// use ffi::{LeapCreateConnection, LeapOpenConnection, LeapPollConnection};
|
|
||||||
|
|
||||||
pub mod error;
|
|
||||||
pub mod event;
|
|
||||||
// pub mod ffi;
|
|
||||||
|
|
||||||
// Cheaty way to ensure only one LeapDevice is created
|
|
||||||
static mut LEAP_DEVICE_EXISTS: bool = false;
|
|
||||||
|
|
||||||
/// Wrapper around a LeapMotion device
|
|
||||||
pub struct LeapDevice {
|
|
||||||
/// Device handle
|
|
||||||
handle: LEAP_CONNECTION,
|
|
||||||
|
|
||||||
/// Storage for incoming messages
|
|
||||||
latest_message: *mut LEAP_CONNECTION_MESSAGE,
|
|
||||||
|
|
||||||
/// Weather the device is connected
|
|
||||||
connected: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LeapDevice {
|
|
||||||
|
|
||||||
/// Open a connection to the first found LeapMotion device and wait for a connection or timeout
|
|
||||||
pub fn new(timeout: Duration) -> Result<Self, LeapError> {
|
|
||||||
|
|
||||||
// Connect to the device
|
|
||||||
let mut device = Self::new_raw()?;
|
|
||||||
|
|
||||||
// Track the start time
|
|
||||||
let start = SystemTime::now();
|
|
||||||
loop {
|
|
||||||
|
|
||||||
// Handle timeout
|
|
||||||
if start.elapsed().unwrap() > timeout {
|
|
||||||
return Err(LeapError::Timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poll for an event and let the handler do its work
|
|
||||||
let _ = device.fetch_event();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(device)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Open a connection to the first found LeapMotion device
|
|
||||||
pub fn new_raw() -> Result<Self, LeapError> {
|
|
||||||
// Handle being called too many times
|
|
||||||
unsafe {
|
|
||||||
if LEAP_DEVICE_EXISTS {
|
|
||||||
panic!("Tried to call LeapDevice::new() more than once!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a connection handle
|
|
||||||
let handle = std::ptr::null_mut();
|
|
||||||
|
|
||||||
// Try to create a connection
|
|
||||||
let result;
|
|
||||||
unsafe {
|
|
||||||
result = LeapCreateConnection(std::ptr::null(), handle);
|
|
||||||
}
|
|
||||||
if result != _eLeapRS_eLeapRS_Success {
|
|
||||||
return Err(result.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to open a connection
|
|
||||||
let result;
|
|
||||||
unsafe {
|
|
||||||
result = LeapOpenConnection(*handle);
|
|
||||||
}
|
|
||||||
if result != _eLeapRS_eLeapRS_Success {
|
|
||||||
return Err(result.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the device flag
|
|
||||||
unsafe {
|
|
||||||
LEAP_DEVICE_EXISTS = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
Ok(Self {
|
|
||||||
handle: *handle,
|
|
||||||
latest_message: std::ptr::null_mut(),
|
|
||||||
connected: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Fetch the latest event from the device
|
|
||||||
pub fn fetch_event(&mut self) -> Result<Event, LeapError> {
|
|
||||||
// Poll for a new message
|
|
||||||
let result;
|
|
||||||
unsafe {
|
|
||||||
result = LeapPollConnection(self.handle, 1000, self.latest_message);
|
|
||||||
}
|
|
||||||
if result != _eLeapRS_eLeapRS_Success {
|
|
||||||
return Err(result.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deref and convert into an event
|
|
||||||
let event: Event;
|
|
||||||
unsafe {
|
|
||||||
event = (*self.latest_message).into();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle checking connection status
|
|
||||||
match event {
|
|
||||||
Event::Connection(_) => self.connected = true,
|
|
||||||
Event::ConnectionLost(_) => self.connected = false,
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for LeapDevice {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,9 +3,8 @@ name = "libodm"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Evan Pratten <ewpratten@gmail.com>"]
|
authors = ["Evan Pratten <ewpratten@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
opencv = "0.53.0"
|
|
||||||
leap-sys = "0.1.1"
|
|
0
libodm/build.rs
Normal file
0
libodm/build.rs
Normal file
68
libodm/cpp/wrapper.cc
Normal file
68
libodm/cpp/wrapper.cc
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "../lib/Leap.h"
|
||||||
|
|
||||||
|
using namespace Leap;
|
||||||
|
|
||||||
|
class LeapEventListener : public Listener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void onConnect(const Controller &);
|
||||||
|
virtual void onDisconnect(const Controller &);
|
||||||
|
virtual void onFrame(const Controller &);
|
||||||
|
};
|
||||||
|
|
||||||
|
void LeapEventListener::onConnect(const Controller &controller)
|
||||||
|
{
|
||||||
|
std::cout << "Connected" << std::endl;
|
||||||
|
// Enable gestures, set Config values:
|
||||||
|
controller.enableGesture(Gesture::TYPE_SWIPE);
|
||||||
|
controller.config().setFloat("Gesture.Swipe.MinLength", 200.0);
|
||||||
|
controller.config().save();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Not dispatched when running in a debugger
|
||||||
|
void LeapEventListener::onDisconnect(const Controller &controller)
|
||||||
|
{
|
||||||
|
std::cout << "Disconnected" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeapEventListener::onFrame(const Controller &controller)
|
||||||
|
{
|
||||||
|
std::cout << "New frame available" << std::endl;
|
||||||
|
Frame frame = controller.frame();
|
||||||
|
|
||||||
|
// Get the camera images
|
||||||
|
ImageList images = frame.images();
|
||||||
|
|
||||||
|
// We require two images
|
||||||
|
if (images.count() != 2){
|
||||||
|
std::cout << "Not enough images received" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a protobuf repr of the image data
|
||||||
|
FrameStreamMessage message;
|
||||||
|
message.set_frame_height(images[0].height());
|
||||||
|
message.set_frame_width(images[0].width());
|
||||||
|
message.set_pixel_bytes(images[0].bytesPerPixel());
|
||||||
|
message.set_left_image((char*) images[0].data());
|
||||||
|
message.set_right_image((char*) images[1].data());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Access to the LeapMotion device along with callback setup
|
||||||
|
Controller controller;
|
||||||
|
LeapEventListener listener;
|
||||||
|
controller.addListener(listener);
|
||||||
|
controller.setPolicy(Leap::Controller::POLICY_IMAGES);
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
6112
libodm/lib/Leap.h
Normal file
6112
libodm/lib/Leap.h
Normal file
File diff suppressed because it is too large
Load Diff
1050
libodm/lib/LeapMath.h
Normal file
1050
libodm/lib/LeapMath.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
libodm/lib/libLeap.so
Executable file
BIN
libodm/lib/libLeap.so
Executable file
Binary file not shown.
0
libodm/src/ffi.rs
Normal file
0
libodm/src/ffi.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
mod ffi;
|
@ -1,11 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "snapscan"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Evan Pratten <ewpratten@gmail.com>"]
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
[dependencies]
|
|
||||||
clap = "2.33.3"
|
|
||||||
libleap = { verison = "0.1.0", path = "../libleap" }
|
|
||||||
libodm = { verison = "0.1.0", path = "../libodm" }
|
|
@ -1,15 +0,0 @@
|
|||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use clap::{value_t, App, Arg};
|
|
||||||
use libleap::LeapDevice;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let matches = App::new("snapscan")
|
|
||||||
.author("Evan Pratten <ewpratten@gmail.com>")
|
|
||||||
.get_matches();
|
|
||||||
|
|
||||||
// Open a connection to the device
|
|
||||||
let device = LeapDevice::new(Duration::from_secs(1)).unwrap();
|
|
||||||
|
|
||||||
println!("Connected to LeapMotion device");
|
|
||||||
}
|
|
Reference in New Issue
Block a user