From 86faa33f83367850e2ceac1173655e58e5613e85 Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Mon, 15 Jul 2013 13:56:37 -0700 Subject: [PATCH 1/5] Added fake Leap finger generation so that Ryan and Jeffrey can work on Leap glove-code without needing a Leap sensor at all times. --- interface/src/Application.cpp | 3 ++ interface/src/Application.h | 3 ++ interface/src/LeapManager.cpp | 71 ++++++++++++++++++++++++++++------- interface/src/LeapManager.h | 5 ++- 4 files changed, 68 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 75f45e8d91..27dac142c9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1677,6 +1677,8 @@ void Application::initMenu() { (_renderCoverageMapV2 = debugMenu->addAction("Render Coverage Map V2"))->setCheckable(true); _renderCoverageMapV2->setShortcut(Qt::SHIFT | Qt::CTRL | Qt::Key_P); + (_simulateLeapHand = debugMenu->addAction("Simulate Leap Hand"))->setCheckable(true); + (_testRaveGlove = debugMenu->addAction("Test RaveGlove"))->setCheckable(true); QMenu* settingsMenu = menuBar->addMenu("Settings"); (_settingsAutosave = settingsMenu->addAction("Autosave"))->setCheckable(true); @@ -1935,6 +1937,7 @@ void Application::update(float deltaTime) { } // Leap finger-sensing device + LeapManager::enableFakeFingers(_simulateLeapHand->isChecked() || _testRaveGlove->isChecked()); LeapManager::nextFrame(); _myAvatar.getHand().setLeapFingers(LeapManager::getFingerTips(), LeapManager::getFingerRoots()); _myAvatar.getHand().setLeapHands(LeapManager::getHandPositions(), LeapManager::getHandNormals()); diff --git a/interface/src/Application.h b/interface/src/Application.h index a4ea633e6d..cb1335887d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -262,6 +262,9 @@ private: QAction* _renderCoverageMapV2; QAction* _renderCoverageMap; + + QAction* _simulateLeapHand; // When there's no Leap, use this to pretend there is one and feed fake hand data + QAction* _testRaveGlove; // Test fancy sparkle-rave-glove mode BandwidthMeter _bandwidthMeter; BandwidthDialog* _bandwidthDialog; diff --git a/interface/src/LeapManager.cpp b/interface/src/LeapManager.cpp index b3d7737969..27c03ef674 100755 --- a/interface/src/LeapManager.cpp +++ b/interface/src/LeapManager.cpp @@ -12,9 +12,14 @@ #include bool LeapManager::_libraryExists = false; +bool LeapManager::_doFakeFingers = false; Leap::Controller* LeapManager::_controller = NULL; HifiLeapListener* LeapManager::_listener = NULL; +namespace { +glm::vec3 fakeHandOffset(0.0f, 50.0f, 50.0f); +} // end anonymous namespace + class HifiLeapListener : public Leap::Listener { public: HifiLeapListener() {} @@ -76,47 +81,87 @@ void LeapManager::terminate() { } void LeapManager::nextFrame() { - if (_listener && _controller) + if (_listener && _controller && _controller->devices().count() > 0) { _listener->onFrame(*_controller); + } +} + +void LeapManager::enableFakeFingers(bool enable) { + _doFakeFingers = enable; +} + +bool LeapManager::controllersExist() { + return _listener && _controller && _controller->devices().count() > 0; } const std::vector& LeapManager::getFingerTips() { - if (_listener) { + if (controllersExist()) { return _listener->fingerTips; } else { - static std::vector empty; - return empty; + static std::vector stubData; + stubData.clear(); + if (_doFakeFingers) { + // Simulated data + float scale = 1.5f; + stubData.push_back(glm::vec3( -60.0f, 0.0f, -40.0f) * scale + fakeHandOffset); + stubData.push_back(glm::vec3( -20.0f, 0.0f, -60.0f) * scale + fakeHandOffset); + stubData.push_back(glm::vec3( 20.0f, 0.0f, -60.0f) * scale + fakeHandOffset); + stubData.push_back(glm::vec3( 60.0f, 0.0f, -40.0f) * scale + fakeHandOffset); + stubData.push_back(glm::vec3( -50.0f, 0.0f, 30.0f) * scale + fakeHandOffset); + } + return stubData; } } const std::vector& LeapManager::getFingerRoots() { - if (_listener) { + if (controllersExist()) { return _listener->fingerRoots; } else { - static std::vector empty; - return empty; + static std::vector stubData; + stubData.clear(); + if (_doFakeFingers) { + // Simulated data + float scale = 0.75f; + stubData.push_back(glm::vec3( -60.0f, 0.0f, -40.0f) * scale + fakeHandOffset); + stubData.push_back(glm::vec3( -20.0f, 0.0f, -60.0f) * scale + fakeHandOffset); + stubData.push_back(glm::vec3( 20.0f, 0.0f, -60.0f) * scale + fakeHandOffset); + stubData.push_back(glm::vec3( 60.0f, 0.0f, -40.0f) * scale + fakeHandOffset); + stubData.push_back(glm::vec3( -50.0f, 0.0f, 30.0f) * scale + fakeHandOffset); + } + return stubData; } } const std::vector& LeapManager::getHandPositions() { - if (_listener) { + if (controllersExist()) { return _listener->handPositions; } else { - static std::vector empty; - return empty; + static std::vector stubData; + stubData.clear(); + if (_doFakeFingers) { + // Simulated data + glm::vec3 handOffset(0.0f, 50.0f, 50.0f); + stubData.push_back(glm::vec3( 0.0f, 0.0f, 0.0f) + fakeHandOffset); + } + return stubData; } } const std::vector& LeapManager::getHandNormals() { - if (_listener) { + if (controllersExist()) { return _listener->handNormals; } else { - static std::vector empty; - return empty; + static std::vector stubData; + stubData.clear(); + if (_doFakeFingers) { + // Simulated data + stubData.push_back(glm::vec3(0.0f, 1.0f, 0.0f)); + } + return stubData; } } diff --git a/interface/src/LeapManager.h b/interface/src/LeapManager.h index f6ed925c6b..e6ac304677 100755 --- a/interface/src/LeapManager.h +++ b/interface/src/LeapManager.h @@ -20,7 +20,9 @@ namespace Leap { class LeapManager { public: - static void nextFrame(); // called once per frame to get new Leap data + 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& getFingerTips(); static const std::vector& getFingerRoots(); static const std::vector& getHandPositions(); @@ -31,6 +33,7 @@ public: 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; }; From c61966ebcd89bdd19df4f5612200587ed4546d64 Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Mon, 15 Jul 2013 14:12:52 -0700 Subject: [PATCH 2/5] made Leap unit-conversion method public --- interface/src/Hand.h | 4 +++- libraries/avatars/src/HandData.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/Hand.h b/interface/src/Hand.h index 244ff0dafd..1c25c85fbc 100755 --- a/interface/src/Hand.h +++ b/interface/src/Hand.h @@ -50,6 +50,9 @@ public: // getters const glm::vec3& getLeapBallPosition (int ball) const { return _leapBalls[ball].position;} + // position conversion + glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition); + private: // disallow copies of the Hand, copy of owning Avatar is disallowed too Hand(const Hand&); @@ -66,7 +69,6 @@ private: // private methods void renderHandSpheres(); void calculateGeometry(); - glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition); }; #endif diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index b0d71b4dee..3de7364071 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -20,6 +20,8 @@ class HandData { public: HandData(AvatarData* owningAvatar); + // These methods return the positions in Leap-relative space. + // To vonvert to world coordinates, use Hand::leapPositionToWorldPosition. const std::vector& getFingerTips() const { return _fingerTips; } const std::vector& getFingerRoots() const { return _fingerRoots; } const std::vector& getHandPositions() const { return _handPositions; } From 0239341127996dac9654463495127332e32489e8 Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Mon, 15 Jul 2013 14:27:58 -0700 Subject: [PATCH 3/5] updated per feedback --- interface/src/LeapManager.cpp | 2 +- libraries/avatars/src/HandData.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/LeapManager.cpp b/interface/src/LeapManager.cpp index 27c03ef674..e65c0f194e 100755 --- a/interface/src/LeapManager.cpp +++ b/interface/src/LeapManager.cpp @@ -81,7 +81,7 @@ void LeapManager::terminate() { } void LeapManager::nextFrame() { - if (_listener && _controller && _controller->devices().count() > 0) { + if (controllersExist()) { _listener->onFrame(*_controller); } } diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index 3de7364071..50a4843153 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -21,7 +21,7 @@ public: HandData(AvatarData* owningAvatar); // These methods return the positions in Leap-relative space. - // To vonvert to world coordinates, use Hand::leapPositionToWorldPosition. + // To convert to world coordinates, use Hand::leapPositionToWorldPosition. const std::vector& getFingerTips() const { return _fingerTips; } const std::vector& getFingerRoots() const { return _fingerRoots; } const std::vector& getHandPositions() const { return _handPositions; } From e937f86822b7d4a7b2a1dc98c6c7816c0fde9db7 Mon Sep 17 00:00:00 2001 From: Eric Johnston Date: Mon, 15 Jul 2013 14:33:09 -0700 Subject: [PATCH 4/5] Build fail fix when Leap libs are not present. --- interface/src/LeapManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/LeapManager.cpp b/interface/src/LeapManager.cpp index e65c0f194e..fe47e527fa 100755 --- a/interface/src/LeapManager.cpp +++ b/interface/src/LeapManager.cpp @@ -91,7 +91,11 @@ void LeapManager::enableFakeFingers(bool enable) { } bool LeapManager::controllersExist() { +#ifdef LEAP_STUBS + return false; +#else return _listener && _controller && _controller->devices().count() > 0; +#endif } const std::vector& LeapManager::getFingerTips() { From 4f1e7863924ac1d1a0301dffde483af9163d7fc4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Jul 2013 16:12:23 -0700 Subject: [PATCH 5/5] Fix for iris rendering; was broken by scale change. --- interface/src/Head.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index cc6f729325..131e0968cc 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -599,7 +599,7 @@ void Head::renderEyeBalls() { _irisProgram->setUniform(_eyePositionLocation, (glm::inverse(rotation) * (Application::getInstance()->getCamera()->getPosition() - _leftEyePosition) + glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f), - 1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / _scale * IRIS_RADIUS)); + 1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS))); glutSolidSphere(0.5f, 15, 15); } @@ -623,7 +623,7 @@ void Head::renderEyeBalls() { _irisProgram->setUniform(_eyePositionLocation, (glm::inverse(rotation) * (Application::getInstance()->getCamera()->getPosition() - _rightEyePosition) + glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f), - 1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / _scale * IRIS_RADIUS)); + 1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS))); glutSolidSphere(0.5f, 15, 15); }