mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 06:23:35 +02:00
Merge branch 'master' of github.com:/worklist/hifi
This commit is contained in:
commit
da2f814b7a
12 changed files with 20 additions and 495 deletions
|
@ -1,52 +0,0 @@
|
||||||
# - Try to find the Leap library
|
|
||||||
#
|
|
||||||
# You must provide a LEAP_ROOT_DIR which contains Lib and Include directories
|
|
||||||
#
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# LEAP_FOUND - system found Leap
|
|
||||||
# LEAP_INCLUDE_DIRS - the Leap include directory
|
|
||||||
# LEAP_LIBRARIES - Link this to use Leap
|
|
||||||
#
|
|
||||||
# Created on 6/21/2013 by Eric Johnston,
|
|
||||||
# adapted from FindLibOVR.cmake by Stephen Birarda
|
|
||||||
# Copyright (c) 2013 High Fidelity
|
|
||||||
#
|
|
||||||
|
|
||||||
if (LEAP_LIBRARIES AND LEAP_INCLUDE_DIRS)
|
|
||||||
# in cache already
|
|
||||||
set(LEAP_FOUND TRUE)
|
|
||||||
else (LEAP_LIBRARIES AND LEAP_INCLUDE_DIRS)
|
|
||||||
find_path(LEAP_INCLUDE_DIRS Leap.h ${LEAP_ROOT_DIR}/include)
|
|
||||||
|
|
||||||
if (LEAP_INCLUDE_DIRS)
|
|
||||||
### If we found the real header, get the library as well.
|
|
||||||
if (APPLE)
|
|
||||||
find_library(LEAP_LIBRARIES libLeap.dylib ${LEAP_ROOT_DIR}/lib/libc++/)
|
|
||||||
elseif (WIN32)
|
|
||||||
find_library(LEAP_LIBRARIES libLeap.dylib ${LEAP_ROOT_DIR}/lib/libc++/)
|
|
||||||
endif ()
|
|
||||||
else ()
|
|
||||||
### If we didn't find the real header, just use the stub header, and no library.
|
|
||||||
find_path(LEAP_INCLUDE_DIRS Leap.h ${LEAP_ROOT_DIR}/stubs/include)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
# If we're using the Leap stubs, there's only a header, no lib.
|
|
||||||
if (LEAP_LIBRARIES AND LEAP_INCLUDE_DIRS)
|
|
||||||
set(LEAP_FOUND TRUE)
|
|
||||||
endif (LEAP_LIBRARIES AND LEAP_INCLUDE_DIRS)
|
|
||||||
|
|
||||||
if (LEAP_FOUND)
|
|
||||||
if (NOT Leap_FIND_QUIETLY)
|
|
||||||
message(STATUS "Found Leap: ${LEAP_LIBRARIES}")
|
|
||||||
endif (NOT Leap_FIND_QUIETLY)
|
|
||||||
else (LEAP_FOUND)
|
|
||||||
if (Leap_FIND_REQUIRED)
|
|
||||||
message(FATAL_ERROR "Could not find Leap")
|
|
||||||
endif (Leap_FIND_REQUIRED)
|
|
||||||
endif (LEAP_FOUND)
|
|
||||||
|
|
||||||
# show the LEAP_INCLUDE_DIRS and LEAP_LIBRARIES variables only in the advanced view
|
|
||||||
mark_as_advanced(LEAP_INCLUDE_DIRS LEAP_LIBRARIES)
|
|
||||||
|
|
||||||
endif (LEAP_LIBRARIES AND LEAP_INCLUDE_DIRS)
|
|
|
@ -11,7 +11,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake
|
||||||
set(FACESHIFT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/faceshift)
|
set(FACESHIFT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/faceshift)
|
||||||
set(LIBOVR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LibOVR)
|
set(LIBOVR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LibOVR)
|
||||||
set(LIBVPX_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LibVPX)
|
set(LIBVPX_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LibVPX)
|
||||||
set(LEAP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/Leap)
|
|
||||||
set(MOTIONDRIVER_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/MotionDriver)
|
set(MOTIONDRIVER_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/MotionDriver)
|
||||||
set(OPENCV_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/OpenCV)
|
set(OPENCV_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/OpenCV)
|
||||||
set(SIXENSE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/Sixense)
|
set(SIXENSE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/Sixense)
|
||||||
|
@ -105,7 +104,6 @@ find_package(Faceshift)
|
||||||
find_package(GLM REQUIRED)
|
find_package(GLM REQUIRED)
|
||||||
find_package(LibOVR)
|
find_package(LibOVR)
|
||||||
find_package(LibVPX)
|
find_package(LibVPX)
|
||||||
find_package(Leap)
|
|
||||||
find_package(MotionDriver)
|
find_package(MotionDriver)
|
||||||
find_package(OpenCV)
|
find_package(OpenCV)
|
||||||
find_package(OpenNI)
|
find_package(OpenNI)
|
||||||
|
@ -196,11 +194,6 @@ if (APPLE)
|
||||||
${QuartzCore}
|
${QuartzCore}
|
||||||
${UVCCAMERACONTROL_LIBRARIES}
|
${UVCCAMERACONTROL_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (LEAP_FOUND)
|
|
||||||
target_link_libraries(${TARGET_NAME} ${LEAP_LIBRARIES})
|
|
||||||
endif(LEAP_FOUND)
|
|
||||||
|
|
||||||
else (APPLE)
|
else (APPLE)
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(GLUT REQUIRED)
|
find_package(GLUT REQUIRED)
|
||||||
|
|
11
interface/external/Leap/readme.txt
vendored
11
interface/external/Leap/readme.txt
vendored
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
Instructions for adding the Leap driver to Interface
|
|
||||||
Eric Johnston, July 10, 2013
|
|
||||||
|
|
||||||
NOTE: Without doing step 2, you will crash at program start time.
|
|
||||||
|
|
||||||
1. Copy the Leap sdk folders (lib, include, etc.) into the interface/external/Leap folder. There should be a folder already there called "stub", and this read me.txt should be there as well.
|
|
||||||
|
|
||||||
2. IMPORTANT: Copy the file interface/external/Leap/lib/libc++/libLeap.dylib to /usr/lib
|
|
||||||
|
|
||||||
3. Delete your build directory, run cmake and build, and you should be all set.
|
|
13
interface/external/Leap/stubs/include/Leap.h
vendored
13
interface/external/Leap/stubs/include/Leap.h
vendored
|
@ -1,13 +0,0 @@
|
||||||
|
|
||||||
// This is an empty stub, used as a placeholder for the real Leap.h
|
|
||||||
// The entire containing Leap folder should be replaced by the one
|
|
||||||
// from the Leap SDK.
|
|
||||||
|
|
||||||
#define LEAP_STUBS // We're using the stubbed-out Leap header
|
|
||||||
|
|
||||||
namespace Leap {
|
|
||||||
class Frame {};
|
|
||||||
class Controller {};
|
|
||||||
class Listener {};
|
|
||||||
}
|
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "Swatch.h"
|
#include "Swatch.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "devices/LeapManager.h"
|
|
||||||
#include "devices/OculusManager.h"
|
#include "devices/OculusManager.h"
|
||||||
#include "devices/TV3DManager.h"
|
#include "devices/TV3DManager.h"
|
||||||
#include "renderer/ProgramObject.h"
|
#include "renderer/ProgramObject.h"
|
||||||
|
@ -1437,7 +1436,6 @@ void Application::terminate() {
|
||||||
// Close serial port
|
// Close serial port
|
||||||
// close(serial_fd);
|
// close(serial_fd);
|
||||||
|
|
||||||
LeapManager::terminate();
|
|
||||||
Menu::getInstance()->saveSettings();
|
Menu::getInstance()->saveSettings();
|
||||||
_rearMirrorTools->saveSettings(_settings);
|
_rearMirrorTools->saveSettings(_settings);
|
||||||
_settings->sync();
|
_settings->sync();
|
||||||
|
@ -1902,8 +1900,6 @@ void Application::init() {
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
LeapManager::initialize();
|
|
||||||
|
|
||||||
gettimeofday(&_timerStart, NULL);
|
gettimeofday(&_timerStart, NULL);
|
||||||
gettimeofday(&_lastTimeUpdated, NULL);
|
gettimeofday(&_lastTimeUpdated, NULL);
|
||||||
|
|
||||||
|
@ -2383,9 +2379,6 @@ void Application::updateHandAndTouch(float deltaTime) {
|
||||||
void Application::updateLeap(float deltaTime) {
|
void Application::updateLeap(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateLeap()");
|
PerformanceWarning warn(showWarnings, "Application::updateLeap()");
|
||||||
|
|
||||||
LeapManager::enableFakeFingers(Menu::getInstance()->isOptionChecked(MenuOption::SimulateLeapHand));
|
|
||||||
LeapManager::nextFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateSixense(float deltaTime) {
|
void Application::updateSixense(float deltaTime) {
|
||||||
|
@ -3676,11 +3669,6 @@ void Application::displayStats() {
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
statsVerticalOffset += PELS_PER_LINE;
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
|
||||||
|
|
||||||
|
|
||||||
// Leap data
|
|
||||||
statsVerticalOffset += PELS_PER_LINE;
|
|
||||||
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)LeapManager::statusString().c_str());
|
|
||||||
|
|
||||||
if (_perfStatsOn) {
|
if (_perfStatsOn) {
|
||||||
// Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups
|
// Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups
|
||||||
char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1];
|
char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1];
|
||||||
|
@ -4152,7 +4140,6 @@ void Application::resetSensors() {
|
||||||
}
|
}
|
||||||
_webcam.reset();
|
_webcam.reset();
|
||||||
_faceshift.reset();
|
_faceshift.reset();
|
||||||
LeapManager::reset();
|
|
||||||
|
|
||||||
if (OculusManager::isConnected()) {
|
if (OculusManager::isConnected()) {
|
||||||
OculusManager::reset();
|
OculusManager::reset();
|
||||||
|
|
|
@ -824,6 +824,10 @@ void Menu::editPreferences() {
|
||||||
leanScale->setValue(applicationInstance->getAvatar()->getLeanScale());
|
leanScale->setValue(applicationInstance->getAvatar()->getLeanScale());
|
||||||
form->addRow("Lean Scale:", leanScale);
|
form->addRow("Lean Scale:", leanScale);
|
||||||
|
|
||||||
|
QDoubleSpinBox* avatarScale = new QDoubleSpinBox();
|
||||||
|
avatarScale->setValue(applicationInstance->getAvatar()->getScale());
|
||||||
|
form->addRow("Avatar Scale:", avatarScale);
|
||||||
|
|
||||||
QSpinBox* audioJitterBufferSamples = new QSpinBox();
|
QSpinBox* audioJitterBufferSamples = new QSpinBox();
|
||||||
audioJitterBufferSamples->setMaximum(10000);
|
audioJitterBufferSamples->setMaximum(10000);
|
||||||
audioJitterBufferSamples->setMinimum(-10000);
|
audioJitterBufferSamples->setMinimum(-10000);
|
||||||
|
@ -887,6 +891,7 @@ void Menu::editPreferences() {
|
||||||
_maxVoxelPacketsPerSecond = maxVoxelsPPS->value();
|
_maxVoxelPacketsPerSecond = maxVoxelsPPS->value();
|
||||||
|
|
||||||
applicationInstance->getAvatar()->setLeanScale(leanScale->value());
|
applicationInstance->getAvatar()->setLeanScale(leanScale->value());
|
||||||
|
applicationInstance->getAvatar()->setNewScale(avatarScale->value());
|
||||||
|
|
||||||
_audioJitterBufferSamples = audioJitterBufferSamples->value();
|
_audioJitterBufferSamples = audioJitterBufferSamples->value();
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
#include "devices/SerialInterface.h"
|
#include "devices/SerialInterface.h"
|
||||||
#include "devices/Transmitter.h"
|
#include "devices/Transmitter.h"
|
||||||
|
|
||||||
static const float MAX_SCALE = 1000.f;
|
|
||||||
static const float MIN_SCALE = .005f;
|
|
||||||
static const float SCALING_RATIO = .05f;
|
static const float SCALING_RATIO = .05f;
|
||||||
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
|
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
|
||||||
static const float RESCALING_TOLERANCE = .02f;
|
static const float RESCALING_TOLERANCE = .02f;
|
||||||
|
|
|
@ -1,352 +0,0 @@
|
||||||
//
|
|
||||||
// LeapManager.cpp
|
|
||||||
// hifi
|
|
||||||
//
|
|
||||||
// Created by Eric Johnston on 6/26/13.
|
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <dlfcn.h> // needed for RTLD_LAZY
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include <Leap.h>
|
|
||||||
|
|
||||||
#include "Application.h"
|
|
||||||
#include "LeapManager.h"
|
|
||||||
#include "Menu.h"
|
|
||||||
|
|
||||||
// Uncomment the next line to use Leap-smoothed stabilized (slower) data.
|
|
||||||
//#define USE_STABILIZED_DATA
|
|
||||||
|
|
||||||
bool LeapManager::_libraryExists = false;
|
|
||||||
bool LeapManager::_doFakeFingers = false;
|
|
||||||
Leap::Controller* LeapManager::_controller = NULL;
|
|
||||||
HifiLeapListener* LeapManager::_listener = NULL;
|
|
||||||
glm::vec3 LeapManager::_baseDrivePosition(0.0f, 150.0f, 0.0f); // experimentally derived
|
|
||||||
|
|
||||||
class HifiLeapListener : public Leap::Listener {
|
|
||||||
public:
|
|
||||||
HifiLeapListener() {}
|
|
||||||
virtual ~HifiLeapListener() {}
|
|
||||||
|
|
||||||
Leap::Frame lastFrame;
|
|
||||||
virtual void onFrame(const Leap::Controller& controller) {
|
|
||||||
#ifndef LEAP_STUBS
|
|
||||||
lastFrame = controller.frame();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void LeapManager::initialize() {
|
|
||||||
#ifndef LEAP_STUBS
|
|
||||||
if (dlopen("/usr/lib/libLeap.dylib", RTLD_LAZY)) {
|
|
||||||
_libraryExists = true;
|
|
||||||
_controller = new Leap::Controller();
|
|
||||||
_listener = new HifiLeapListener();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static PalmData* getRightmostPalm() {
|
|
||||||
PalmData* rightmostPalm = NULL;
|
|
||||||
Hand& hand = Application::getInstance()->getAvatar()->getHand();
|
|
||||||
for (int i = 0; i < hand.getNumPalms(); i++) {
|
|
||||||
PalmData* palm = &hand.getPalms()[i];
|
|
||||||
if (palm->isActive() && (rightmostPalm == NULL || palm->getRawPosition().x > rightmostPalm->getRawPosition().x)) {
|
|
||||||
rightmostPalm = palm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rightmostPalm;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LeapManager::reset() {
|
|
||||||
PalmData* rightmostPalm = getRightmostPalm();
|
|
||||||
if (rightmostPalm != NULL) {
|
|
||||||
_baseDrivePosition = rightmostPalm->getRawPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LeapManager::terminate() {
|
|
||||||
delete _listener;
|
|
||||||
delete _controller;
|
|
||||||
_listener = NULL;
|
|
||||||
_controller = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LeapManager::nextFrame() {
|
|
||||||
// Apply the frame data directly to the avatar.
|
|
||||||
MyAvatar* avatar = Application::getInstance()->getAvatar();
|
|
||||||
Hand& hand = avatar->getHand();
|
|
||||||
|
|
||||||
// If we actually get valid Leap data, this will be set to true;
|
|
||||||
bool gotRealData = false;
|
|
||||||
|
|
||||||
if (controllersExist()) {
|
|
||||||
_listener->onFrame(*_controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef LEAP_STUBS
|
|
||||||
if (controllersExist()) {
|
|
||||||
gotRealData = true;
|
|
||||||
// First, see which palms and fingers are still valid.
|
|
||||||
Leap::Frame& frame = _listener->lastFrame;
|
|
||||||
|
|
||||||
// Note that this is O(n^2) at worst, but n is very small.
|
|
||||||
|
|
||||||
// After this many frames of no data, assume the digit is lost.
|
|
||||||
const int assumeLostAfterFrameCount = 10;
|
|
||||||
|
|
||||||
// Increment our frame data counters
|
|
||||||
for (size_t i = 0; i < hand.getNumPalms(); ++i) {
|
|
||||||
PalmData& palm = hand.getPalms()[i];
|
|
||||||
palm.incrementFramesWithoutData();
|
|
||||||
if (palm.getFramesWithoutData() > assumeLostAfterFrameCount) {
|
|
||||||
palm.setActive(false);
|
|
||||||
}
|
|
||||||
for (size_t f = 0; f < palm.getNumFingers(); ++f) {
|
|
||||||
FingerData& finger = palm.getFingers()[f];
|
|
||||||
finger.incrementFramesWithoutData();
|
|
||||||
if (finger.getFramesWithoutData() > assumeLostAfterFrameCount) {
|
|
||||||
finger.setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t numLeapHands = frame.hands().count();
|
|
||||||
std::vector<PalmData*> palmAssignment(numLeapHands);
|
|
||||||
|
|
||||||
// Look for matches
|
|
||||||
for (size_t index = 0; index < numLeapHands; ++index) {
|
|
||||||
PalmData* takeoverCandidate = NULL;
|
|
||||||
palmAssignment[index] = NULL;
|
|
||||||
Leap::Hand leapHand = frame.hands()[index];
|
|
||||||
int id = leapHand.id();
|
|
||||||
if (leapHand.isValid()) {
|
|
||||||
for (size_t i = 0; i < hand.getNumPalms() && palmAssignment[index] == NULL; ++i) {
|
|
||||||
PalmData& palm = hand.getPalms()[i];
|
|
||||||
if (palm.getLeapID() == id) {
|
|
||||||
// Found hand with the same ID. We're set!
|
|
||||||
palmAssignment[index] = &palm;
|
|
||||||
palm.resetFramesWithoutData();
|
|
||||||
}
|
|
||||||
else if (palm.getFramesWithoutData() > assumeLostAfterFrameCount) {
|
|
||||||
takeoverCandidate = &palm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (palmAssignment[index] == NULL) {
|
|
||||||
palmAssignment[index] = takeoverCandidate;
|
|
||||||
}
|
|
||||||
if (palmAssignment[index] == NULL) {
|
|
||||||
palmAssignment[index] = &hand.addNewPalm();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the assignments
|
|
||||||
for (size_t index = 0; index < numLeapHands; ++index) {
|
|
||||||
if (palmAssignment[index]) {
|
|
||||||
Leap::Hand leapHand = frame.hands()[index];
|
|
||||||
PalmData& palm = *(palmAssignment[index]);
|
|
||||||
|
|
||||||
palm.resetFramesWithoutData();
|
|
||||||
palm.setLeapID(leapHand.id());
|
|
||||||
palm.setActive(true);
|
|
||||||
const Leap::Vector pos = leapHand.palmPosition();
|
|
||||||
const Leap::Vector normal = leapHand.palmNormal();
|
|
||||||
palm.setRawPosition(glm::vec3(pos.x, pos.y, pos.z));
|
|
||||||
palm.setRawNormal(glm::vec3(normal.x, normal.y, normal.z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for fingers per palm
|
|
||||||
for (size_t i = 0; i < hand.getNumPalms(); ++i) {
|
|
||||||
PalmData& palm = hand.getPalms()[i];
|
|
||||||
if (palm.isActive()) {
|
|
||||||
Leap::Hand leapHand = frame.hand(palm.getLeapID());
|
|
||||||
if (leapHand.isValid()) {
|
|
||||||
int numLeapFingers = leapHand.fingers().count();
|
|
||||||
std::vector<FingerData*> fingerAssignment(numLeapFingers);
|
|
||||||
|
|
||||||
|
|
||||||
// Look for matches
|
|
||||||
for (size_t index = 0; index < numLeapFingers; ++index) {
|
|
||||||
FingerData* takeoverCandidate = NULL;
|
|
||||||
fingerAssignment[index] = NULL;
|
|
||||||
Leap::Finger leapFinger = leapHand.fingers()[index];
|
|
||||||
int id = leapFinger.id();
|
|
||||||
if (leapFinger.isValid()) {
|
|
||||||
for (size_t f = 0; f < palm.getNumFingers() && fingerAssignment[index] == NULL; ++f) {
|
|
||||||
FingerData& finger = palm.getFingers()[f];
|
|
||||||
if (finger.getLeapID() == id) {
|
|
||||||
// Found hand with the same ID. We're set!
|
|
||||||
fingerAssignment[index] = &finger;
|
|
||||||
}
|
|
||||||
else if (finger.getFramesWithoutData() > assumeLostAfterFrameCount) {
|
|
||||||
takeoverCandidate = &finger;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If we didn't find a match, but we found an unused finger, us it.
|
|
||||||
if (fingerAssignment[index] == NULL) {
|
|
||||||
fingerAssignment[index] = takeoverCandidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the assignments
|
|
||||||
for (size_t index = 0; index < numLeapFingers; ++index) {
|
|
||||||
if (fingerAssignment[index]) {
|
|
||||||
Leap::Finger leapFinger = leapHand.fingers()[index];
|
|
||||||
FingerData& finger = *(fingerAssignment[index]);
|
|
||||||
|
|
||||||
finger.resetFramesWithoutData();
|
|
||||||
finger.setLeapID(leapFinger.id());
|
|
||||||
finger.setActive(true);
|
|
||||||
#ifdef USE_STABILIZED_DATA
|
|
||||||
const Leap::Vector tip = leapFinger.stabilizedTipPosition();
|
|
||||||
#else
|
|
||||||
const Leap::Vector tip = leapFinger.tipPosition();
|
|
||||||
#endif
|
|
||||||
const Leap::Vector root = tip - leapFinger.direction() * leapFinger.length();
|
|
||||||
finger.setRawTipPosition(glm::vec3(tip.x, tip.y, tip.z));
|
|
||||||
finger.setRawRootPosition(glm::vec3(root.x, root.y, root.z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!gotRealData) {
|
|
||||||
if (_doFakeFingers) {
|
|
||||||
// There's no real Leap data and we need to fake it.
|
|
||||||
for (size_t i = 0; i < hand.getNumPalms(); ++i) {
|
|
||||||
static const glm::vec3 fakeHandOffsets[] = {
|
|
||||||
glm::vec3( -250.0f, 50.0f, 50.0f),
|
|
||||||
glm::vec3( 250.0f, 50.0f, 50.0f)
|
|
||||||
};
|
|
||||||
static const glm::vec3 fakeHandFingerMirrors[] = {
|
|
||||||
glm::vec3( -1.0f, 1.0f, 1.0f),
|
|
||||||
glm::vec3( 1.0f, 1.0f, 1.0f)
|
|
||||||
};
|
|
||||||
static const glm::vec3 fakeFingerPositions[] = {
|
|
||||||
glm::vec3( -60.0f, 0.0f, -40.0f),
|
|
||||||
glm::vec3( -20.0f, 0.0f, -60.0f),
|
|
||||||
glm::vec3( 20.0f, 0.0f, -60.0f),
|
|
||||||
glm::vec3( 60.0f, 0.0f, -40.0f),
|
|
||||||
glm::vec3( -50.0f, 0.0f, 30.0f)
|
|
||||||
};
|
|
||||||
|
|
||||||
PalmData& palm = hand.getPalms()[i];
|
|
||||||
palm.setActive(true);
|
|
||||||
// Simulated data
|
|
||||||
|
|
||||||
palm.setRawPosition(glm::vec3( 0.0f, 0.0f, 0.0f) + fakeHandOffsets[i]);
|
|
||||||
palm.setRawNormal(glm::vec3(0.0f, -1.0f, 0.0f));
|
|
||||||
|
|
||||||
for (size_t f = 0; f < palm.getNumFingers(); ++f) {
|
|
||||||
FingerData& finger = palm.getFingers()[f];
|
|
||||||
finger.setActive(true);
|
|
||||||
const float tipScale = 1.5f;
|
|
||||||
const float rootScale = 0.75f;
|
|
||||||
glm::vec3 fingerPos = fakeFingerPositions[f] * fakeHandFingerMirrors[i];
|
|
||||||
finger.setRawTipPosition(fingerPos * tipScale + fakeHandOffsets[i]);
|
|
||||||
finger.setRawRootPosition(fingerPos * rootScale + fakeHandOffsets[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Just deactivate everything.
|
|
||||||
for (size_t i = 0; i < hand.getNumPalms(); ++i) {
|
|
||||||
PalmData& palm = hand.getPalms()[i];
|
|
||||||
palm.setActive(false);
|
|
||||||
for (size_t f = 0; f < palm.getNumFingers(); ++f) {
|
|
||||||
FingerData& finger = palm.getFingers()[f];
|
|
||||||
finger.setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hand.updateFingerTrails();
|
|
||||||
|
|
||||||
// if Leap drive is enabled, drive avatar based on Leap input
|
|
||||||
if (!(Menu::getInstance()->isOptionChecked(MenuOption::LeapDrive) && gotRealData)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
glm::vec3 relativePosition;
|
|
||||||
glm::vec3 eulerAngles;
|
|
||||||
PalmData* rightmostPalm = getRightmostPalm();
|
|
||||||
if (rightmostPalm != NULL) {
|
|
||||||
relativePosition = rightmostPalm->getRawPosition() - _baseDrivePosition;
|
|
||||||
|
|
||||||
glm::vec3 directionSum;
|
|
||||||
int activeFingerCount = 0;
|
|
||||||
for (int i = 0; i < rightmostPalm->getNumFingers(); i++) {
|
|
||||||
FingerData& finger = rightmostPalm->getFingers()[i];
|
|
||||||
glm::vec3 fingerVector = finger.getTipRawPosition() - rightmostPalm->getRawPosition();
|
|
||||||
if (finger.isActive() && glm::length(fingerVector) > EPSILON) {
|
|
||||||
directionSum += glm::normalize(fingerVector);
|
|
||||||
activeFingerCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const int MIN_DIRECTION_FINGER_COUNT = 3;
|
|
||||||
glm::vec3 right;
|
|
||||||
if (activeFingerCount >= MIN_DIRECTION_FINGER_COUNT) {
|
|
||||||
right = glm::normalize(glm::cross(glm::normalize(directionSum), -rightmostPalm->getRawNormal()));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
right = glm::normalize(glm::cross(IDENTITY_FRONT, -rightmostPalm->getRawNormal()));
|
|
||||||
}
|
|
||||||
eulerAngles = safeEulerAngles(glm::quat_cast(glm::mat3(right, -rightmostPalm->getRawNormal(),
|
|
||||||
glm::cross(right, -rightmostPalm->getRawNormal()))));
|
|
||||||
}
|
|
||||||
const float LINEAR_DRIVE_SCALE = 0.01f;
|
|
||||||
const float LINEAR_DEAD_ZONE = 0.25f;
|
|
||||||
avatar->setDriveKeys(FWD, glm::clamp(-relativePosition.z * LINEAR_DRIVE_SCALE - LINEAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
avatar->setDriveKeys(BACK, glm::clamp(relativePosition.z * LINEAR_DRIVE_SCALE - LINEAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
avatar->setDriveKeys(LEFT, glm::clamp(-relativePosition.x * LINEAR_DRIVE_SCALE - LINEAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
avatar->setDriveKeys(RIGHT, glm::clamp(relativePosition.x * LINEAR_DRIVE_SCALE - LINEAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
avatar->setDriveKeys(UP, glm::clamp(relativePosition.y * LINEAR_DRIVE_SCALE - LINEAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
avatar->setDriveKeys(DOWN, glm::clamp(-relativePosition.y * LINEAR_DRIVE_SCALE - LINEAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
const float ANGULAR_DRIVE_SCALE = 0.05f;
|
|
||||||
const float ANGULAR_DEAD_ZONE = 0.75f;
|
|
||||||
avatar->setDriveKeys(ROT_LEFT, glm::clamp(glm::max(eulerAngles.y, eulerAngles.z) * ANGULAR_DRIVE_SCALE -
|
|
||||||
ANGULAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
avatar->setDriveKeys(ROT_RIGHT, glm::clamp(glm::max(-eulerAngles.y, -eulerAngles.z) * ANGULAR_DRIVE_SCALE -
|
|
||||||
ANGULAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
avatar->setDriveKeys(ROT_UP, glm::clamp(eulerAngles.x * ANGULAR_DRIVE_SCALE - ANGULAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
avatar->setDriveKeys(ROT_DOWN, glm::clamp(-eulerAngles.x * ANGULAR_DRIVE_SCALE - ANGULAR_DEAD_ZONE, 0.0f, 1.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LeapManager::enableFakeFingers(bool enable) {
|
|
||||||
_doFakeFingers = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LeapManager::controllersExist() {
|
|
||||||
#ifdef LEAP_STUBS
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return _listener && _controller && _controller->devices().count() > 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string LeapManager::statusString() {
|
|
||||||
std::stringstream leapString;
|
|
||||||
#ifndef LEAP_STUBS
|
|
||||||
if (!_libraryExists)
|
|
||||||
leapString << "Leap library at /usr/lib/libLeap.dylib does not exist.";
|
|
||||||
else if (!_controller || !_listener || !_controller->devices().count())
|
|
||||||
leapString << "Leap controller is not attached.";
|
|
||||||
else {
|
|
||||||
leapString << "Leap pointables: " << _listener->lastFrame.pointables().count();
|
|
||||||
if (_listener->lastFrame.pointables().count() > 0) {
|
|
||||||
Leap::Vector pos = _listener->lastFrame.pointables()[0].tipPosition();
|
|
||||||
leapString << " pos: " << pos.x << " " << pos.y << " " << pos.z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return leapString.str();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
//
|
|
||||||
// LeapManager.h
|
|
||||||
// hifi
|
|
||||||
//
|
|
||||||
// Created by Eric Johnston on 6/26/13.
|
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __hifi__LeapManager__
|
|
||||||
#define __hifi__LeapManager__
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class Avatar;
|
|
||||||
class HifiLeapListener;
|
|
||||||
namespace Leap {
|
|
||||||
class Controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LeapManager {
|
|
||||||
public:
|
|
||||||
static void nextFrame(); // called once per frame to get new Leap data
|
|
||||||
static bool controllersExist(); // Returns true if there's at least one active Leap plugged in
|
|
||||||
static void enableFakeFingers(bool enable); // put fake data in if there's no Leap plugged in
|
|
||||||
static const std::vector<glm::vec3>& getFingerTips();
|
|
||||||
static const std::vector<glm::vec3>& getFingerRoots();
|
|
||||||
static const std::vector<glm::vec3>& getHandPositions();
|
|
||||||
static const std::vector<glm::vec3>& getHandNormals();
|
|
||||||
static std::string statusString();
|
|
||||||
static void initialize();
|
|
||||||
static void reset();
|
|
||||||
static void terminate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool _libraryExists; // The library is present, so we won't crash if we call it.
|
|
||||||
static bool _doFakeFingers;
|
|
||||||
static Leap::Controller* _controller;
|
|
||||||
static HifiLeapListener* _listener;
|
|
||||||
static glm::vec3 _baseDrivePosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* defined(__hifi__LeapManager__) */
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QSyntaxHighlighter>
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "AbstractLoggerInterface.h"
|
#include "AbstractLoggerInterface.h"
|
||||||
|
|
||||||
|
|
|
@ -295,3 +295,13 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
|
|
||||||
return sourceBuffer - startPosition;
|
return sourceBuffer - startPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarData::setNewScale(float newScale) {
|
||||||
|
if (newScale > MAX_SCALE) {
|
||||||
|
newScale = MAX_SCALE;
|
||||||
|
} else if (newScale < MIN_SCALE) {
|
||||||
|
newScale = MIN_SCALE;
|
||||||
|
}
|
||||||
|
_newScale = newScale;
|
||||||
|
qDebug() << "Changed scale to " << _newScale << "\n";
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ const int HAND_STATE_START_BIT = 2; // 3rd and 4th bits
|
||||||
const int IS_FACESHIFT_CONNECTED = 4; // 5th bit
|
const int IS_FACESHIFT_CONNECTED = 4; // 5th bit
|
||||||
const int IS_CHAT_CIRCLING_ENABLED = 5;
|
const int IS_CHAT_CIRCLING_ENABLED = 5;
|
||||||
|
|
||||||
|
static const float MAX_SCALE = 1000.f;
|
||||||
|
static const float MIN_SCALE = .005f;
|
||||||
|
|
||||||
const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation
|
const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation
|
||||||
|
|
||||||
enum KeyState
|
enum KeyState
|
||||||
|
@ -80,7 +83,7 @@ public:
|
||||||
|
|
||||||
// Scale
|
// Scale
|
||||||
float getNewScale() const { return _newScale; }
|
float getNewScale() const { return _newScale; }
|
||||||
void setNewScale(float newScale) { _newScale = newScale; }
|
void setNewScale(float);
|
||||||
|
|
||||||
// Hand State
|
// Hand State
|
||||||
void setHandState(char s) { _handState = s; }
|
void setHandState(char s) { _handState = s; }
|
||||||
|
|
Loading…
Reference in a new issue