diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9ce6cc9b25..c67ba9c81f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -143,7 +143,6 @@ #include "avatar/MyHead.h" #include "CrashHandler.h" #include "devices/DdeFaceTracker.h" -#include "devices/Leapmotion.h" #include "DiscoverabilityManager.h" #include "GLCanvas.h" #include "InterfaceDynamicFactory.h" @@ -1809,8 +1808,6 @@ Application::~Application() { // remove the NodeList from the DependencyManager DependencyManager::destroy(); - Leapmotion::destroy(); - if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { steamClient->shutdown(); } @@ -3977,8 +3974,6 @@ void Application::init() { qCDebug(interfaceapp) << "Loaded settings"; - Leapmotion::init(); - // fire off an immediate domain-server check in now that settings are loaded DependencyManager::get()->sendDomainServerCheckIn(); @@ -4451,7 +4446,6 @@ void Application::update(float deltaTime) { { PerformanceTimer perfTimer("devices"); - DeviceTracker::updateAll(); FaceTracker* tracker = getSelectedFaceTracker(); if (tracker && Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking) != tracker->isMuted()) { @@ -4519,8 +4513,6 @@ void Application::update(float deltaTime) { keyboardMousePlugin->pluginUpdate(deltaTime, calibrationData); } - _controllerScriptingInterface->updateInputControllers(); - // Transfer the user inputs to the driveKeys // FIXME can we drop drive keys and just have the avatar read the action states directly? myAvatar->clearDriveKeys(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 463069430d..f8f66aded5 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -547,9 +547,6 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false, avatar.get(), SLOT(setEnableDebugDrawHandControllers(bool))); - MenuWrapper* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion"); - addCheckableActionToQMenuAndActionHash(leapOptionsMenu, MenuOption::LeapMotionOnHMD, 0, false); - // Developer > Entities >>> MenuWrapper* entitiesOptionsMenu = developerMenu->addMenu("Entities"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 41bf89a20a..0dce84e8a5 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -115,7 +115,6 @@ namespace MenuOption { const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IndependentMode = "Independent Mode"; const QString ActionMotorControl = "Enable Default Motor Control"; - const QString LeapMotionOnHMD = "Leap Motion on HMD"; const QString LoadScript = "Open and Run Script File..."; const QString LoadScriptURL = "Open and Run Script from URL..."; const QString LodTools = "LOD Tools"; diff --git a/interface/src/devices/Leapmotion.cpp b/interface/src/devices/Leapmotion.cpp deleted file mode 100644 index c643042300..0000000000 --- a/interface/src/devices/Leapmotion.cpp +++ /dev/null @@ -1,246 +0,0 @@ -// -// Created by Sam Cake on 6/2/2014 -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "Leapmotion.h" - -#include - -#include "Menu.h" - -const int PALMROOT_NUM_JOINTS = 3; -const int FINGER_NUM_JOINTS = 4; -const int HAND_NUM_JOINTS = FINGER_NUM_JOINTS*5+PALMROOT_NUM_JOINTS; - -const DeviceTracker::Name Leapmotion::NAME = "Leapmotion"; - -// find the index of a joint from -// the side: true = right -// the finger & the bone: -// finger in [0..4] : bone in [0..3] a finger phalange -// [-1] up the hand branch : bone in [0..2] <=> [ hand, forearm, arm] -MotionTracker::Index evalJointIndex(bool isRightSide, int finger, int bone) { - - MotionTracker::Index offset = 1 // start after root - + (int(isRightSide) * HAND_NUM_JOINTS) // then offset for side - + PALMROOT_NUM_JOINTS; // then add the arm/forearm/hand chain - if (finger >= 0) { - // from there go down in the correct finger and bone - return offset + (finger * FINGER_NUM_JOINTS) + bone; - } else { - // or go back up for the correct root bone - return offset - 1 - bone; - } -} - -// static -void Leapmotion::init() { - DeviceTracker* device = DeviceTracker::getDevice(NAME); - - if (!device) { - // create a new Leapmotion and register it - Leapmotion* leap = new Leapmotion(); - DeviceTracker::registerDevice(NAME, leap); - } -} - -// static -void Leapmotion::destroy() { - DeviceTracker::destroyDevice(NAME); -} - -// static -Leapmotion* Leapmotion::getInstance() { - DeviceTracker* device = DeviceTracker::getDevice(NAME); - if (!device) { - // create a new Leapmotion and register it - device = new Leapmotion(); - DeviceTracker::registerDevice(NAME, device); - } - return dynamic_cast< Leapmotion* > (device); -} - -Leapmotion::Leapmotion() : - MotionTracker(), - _active(false) -{ - // Create the Leapmotion joint hierarchy - std::vector< Semantic > sides; - sides.push_back("joint_L_"); - sides.push_back("joint_R_"); - - std::vector< Semantic > rootBones; - rootBones.push_back("elbow"); - rootBones.push_back("wrist"); - rootBones.push_back("hand"); - - std::vector< Semantic > fingers; - fingers.push_back("thumb"); - fingers.push_back("index"); - fingers.push_back("middle"); - fingers.push_back("ring"); - fingers.push_back("pinky"); - - std::vector< Semantic > fingerBones; - fingerBones.push_back("1"); - fingerBones.push_back("2"); - fingerBones.push_back("3"); - fingerBones.push_back("4"); - - std::vector< Index > palms; - for (unsigned int s = 0; s < sides.size(); s++) { - Index rootJoint = 0; - for (unsigned int rb = 0; rb < rootBones.size(); rb++) { - rootJoint = addJoint(sides[s] + rootBones[rb], rootJoint); - } - - // capture the hand index for debug - palms.push_back(rootJoint); - - for (unsigned int f = 0; f < fingers.size(); f++) { - for (unsigned int b = 0; b < fingerBones.size(); b++) { - rootJoint = addJoint(sides[s] + fingers[f] + fingerBones[b], rootJoint); - } - } - } - -#ifdef HAVE_LEAPMOTION - if (Menu::getInstance()->isOptionChecked(MenuOption::LeapMotionOnHMD)) { - _controller.setPolicyFlags(Leap::Controller::POLICY_OPTIMIZE_HMD); - } -#endif -} - -Leapmotion::~Leapmotion() { -} - -#ifdef HAVE_LEAPMOTION -glm::quat quatFromLeapBase(float sideSign, const Leap::Matrix& basis) { - - // fix the handness to right and always... - glm::vec3 xAxis = glm::normalize(sideSign * glm::vec3(basis.xBasis.x, basis.xBasis.y, basis.xBasis.z)); - glm::vec3 yAxis = glm::normalize(glm::vec3(basis.yBasis.x, basis.yBasis.y, basis.yBasis.z)); - glm::vec3 zAxis = glm::normalize(glm::vec3(basis.zBasis.x, basis.zBasis.y, basis.zBasis.z)); - - xAxis = glm::normalize(glm::cross(yAxis, zAxis)); - - glm::quat orientation = (glm::quat_cast(glm::mat3(xAxis, yAxis, zAxis))); - return orientation; -} - -glm::vec3 vec3FromLeapVector(const Leap::Vector& vec) { - return glm::vec3(vec.x * METERS_PER_MILLIMETER, vec.y * METERS_PER_MILLIMETER, vec.z * METERS_PER_MILLIMETER); -} - -#endif - -void Leapmotion::update() { -#ifdef HAVE_LEAPMOTION - bool wasActive = _active; - _active = _controller.isConnected(); - - if (_active || wasActive) { - // Go through all the joints and increment their counter since last update. - // Increment all counters once after controller first becomes inactive so that each joint reports itself as inactive. - // TODO C++11 for (auto jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { - for (JointTracker::Vector::iterator jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { - (*jointIt).tickNewFrame(); - } - } - - if (!_active) { - return; - } - - // Get the most recent frame and report some basic information - const Leap::Frame frame = _controller.frame(); - static int64_t lastFrameID = -1; - int64_t newFrameID = frame.id(); - - // If too soon then exit - if (lastFrameID >= newFrameID) - return; - - glm::vec3 delta(0.0f); - glm::quat handOri; - if (!frame.hands().isEmpty()) { - for (int handNum = 0; handNum < frame.hands().count(); handNum++) { - - const Leap::Hand hand = frame.hands()[handNum]; - int side = (hand.isRight() ? 1 : -1); - - JointTracker* parentJointTracker = _jointsArray.data(); - - - int rootBranchIndex = -1; - - Leap::Arm arm = hand.arm(); - if (arm.isValid()) { - glm::quat ori = quatFromLeapBase(float(side), arm.basis()); - glm::vec3 pos = vec3FromLeapVector(arm.elbowPosition()); - JointTracker* elbow = editJointTracker(evalJointIndex((side > 0), rootBranchIndex, 2)); // 2 is the index of the elbow joint - elbow->editAbsFrame().setTranslation(pos); - elbow->editAbsFrame().setRotation(ori); - elbow->updateLocFromAbsTransform(parentJointTracker); - elbow->activeFrame(); - parentJointTracker = elbow; - - pos = vec3FromLeapVector(arm.wristPosition()); - JointTracker* wrist = editJointTracker(evalJointIndex((side > 0), rootBranchIndex, 1)); // 1 is the index of the wrist joint - wrist->editAbsFrame().setTranslation(pos); - wrist->editAbsFrame().setRotation(ori); - wrist->updateLocFromAbsTransform(parentJointTracker); - wrist->activeFrame(); - parentJointTracker = wrist; - } - - JointTracker* palmJoint = NULL; - { - glm::vec3 pos = vec3FromLeapVector(hand.palmPosition()); - glm::quat ori = quatFromLeapBase(float(side), hand.basis()); - - palmJoint = editJointTracker(evalJointIndex((side > 0), rootBranchIndex, 0)); // 0 is the index of the palm joint - palmJoint->editAbsFrame().setTranslation(pos); - palmJoint->editAbsFrame().setRotation(ori); - palmJoint->updateLocFromAbsTransform(parentJointTracker); - palmJoint->activeFrame(); - } - - // Check if the hand has any fingers - const Leap::FingerList fingers = hand.fingers(); - if (!fingers.isEmpty()) { - // For every fingers in the list - for (int i = 0; i < fingers.count(); ++i) { - // Reset the parent joint to the palmJoint for every finger traversal - parentJointTracker = palmJoint; - - // surprisingly, Leap::Finger::Type start at 0 for thumb a until 4 for the pinky - Index fingerIndex = evalJointIndex((side > 0), int(fingers[i].type()), 0); - - // let's update the finger's joints - for (int b = 0; b < FINGER_NUM_JOINTS; b++) { - Leap::Bone::Type type = Leap::Bone::Type(b + Leap::Bone::TYPE_METACARPAL); - Leap::Bone bone = fingers[i].bone(type); - JointTracker* ljointTracker = editJointTracker(fingerIndex + b); - if (bone.isValid()) { - Leap::Vector bp = bone.nextJoint(); - - ljointTracker->editAbsFrame().setTranslation(vec3FromLeapVector(bp)); - ljointTracker->editAbsFrame().setRotation(quatFromLeapBase(float(side), bone.basis())); - ljointTracker->updateLocFromAbsTransform(parentJointTracker); - ljointTracker->activeFrame(); - } - parentJointTracker = ljointTracker; - } - } - } - } - } - - lastFrameID = newFrameID; -#endif -} diff --git a/interface/src/devices/Leapmotion.h b/interface/src/devices/Leapmotion.h deleted file mode 100644 index a119821846..0000000000 --- a/interface/src/devices/Leapmotion.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// Created by Sam Cake on 6/2/2014 -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_Leapmotion_h -#define hifi_Leapmotion_h - -#include - -#include - -#ifdef HAVE_LEAPMOTION -#include -#endif - -/// Handles interaction with the Leapmotion skeleton tracking suit. -class Leapmotion : public MotionTracker { -public: - static const Name NAME; - - static void init(); - static void destroy(); - - /// Leapmotion MotionTracker factory - static Leapmotion* getInstance(); - - bool isActive() const { return _active; } - - virtual void update() override; - -protected: - Leapmotion(); - virtual ~Leapmotion(); - -private: -#ifdef HAVE_LEAPMOTION - Leap::Listener _listener; - Leap::Controller _controller; -#endif - - bool _active; -}; - -#endif // hifi_Leapmotion_h diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index f3ec3cd79d..9fbd01817a 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -17,7 +17,6 @@ #include #include "Application.h" -#include void ControllerScriptingInterface::handleMetaEvent(HFMetaEvent* event) { if (event->type() == HFActionEvent::startType()) { @@ -97,86 +96,6 @@ QVariant ControllerScriptingInterface::getRecommendedOverlayRect() const { return qRectToVariant(rect); } -controller::InputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) { - // This is where we retrieve the Device Tracker category and then the sub tracker within it - auto icIt = _inputControllers.find(0); - if (icIt != _inputControllers.end()) { - return (*icIt).second.get(); - } - - // Look for device - DeviceTracker::ID deviceID = DeviceTracker::getDeviceID(deviceName.toStdString()); - if (deviceID < 0) { - deviceID = 0; - } - // TODO in this current implementation, we just pick the device assuming there is one (normally the Leapmotion) - // in the near future we need to change that to a real mapping between the devices and the deviceName - // ALso we need to expand the spec so we can fall back on the "default" controller per categories - - if (deviceID >= 0) { - // TODO here again the assumption it's the LeapMotion and so it's a MOtionTracker, this would need to be changed to support different types of devices - MotionTracker* motionTracker = dynamic_cast< MotionTracker* > (DeviceTracker::getDevice(deviceID)); - if (motionTracker) { - MotionTracker::Index trackerID = motionTracker->findJointIndex(tracker.toStdString()); - if (trackerID >= 0) { - controller::InputController::Pointer inputController = std::make_shared(deviceID, trackerID, this); - controller::InputController::Key key = inputController->getKey(); - _inputControllers.insert(InputControllerMap::value_type(key, inputController)); - return inputController.get(); - } - } - } - - return nullptr; -} - -void ControllerScriptingInterface::releaseInputController(controller::InputController* input) { - _inputControllers.erase(input->getKey()); -} - -void ControllerScriptingInterface::updateInputControllers() { - for (auto it = _inputControllers.begin(); it != _inputControllers.end(); it++) { - (*it).second->update(); - } -} - -InputController::InputController(int deviceTrackerId, int subTrackerId, QObject* parent) : - _deviceTrackerId(deviceTrackerId), - _subTrackerId(subTrackerId), - _isActive(false) -{ -} - -void InputController::update() { - _isActive = false; - - // TODO for now the InputController is only supporting a JointTracker from a MotionTracker - MotionTracker* motionTracker = dynamic_cast< MotionTracker*> (DeviceTracker::getDevice(_deviceTrackerId)); - if (motionTracker) { - if ((int)_subTrackerId < motionTracker->numJointTrackers()) { - const MotionTracker::JointTracker* joint = motionTracker->getJointTracker(_subTrackerId); - - if (joint->isActive()) { - joint->getAbsFrame().getTranslation(_eventCache.absTranslation); - joint->getAbsFrame().getRotation(_eventCache.absRotation); - joint->getLocFrame().getTranslation(_eventCache.locTranslation); - joint->getLocFrame().getRotation(_eventCache.locRotation); - - _isActive = true; - //emit spatialEvent(_eventCache); - } - } - } -} - -const unsigned int INPUTCONTROLLER_KEY_DEVICE_OFFSET = 16; -const unsigned int INPUTCONTROLLER_KEY_DEVICE_MASK = 16; - -InputController::Key InputController::getKey() const { - return (((_deviceTrackerId & INPUTCONTROLLER_KEY_DEVICE_MASK) << INPUTCONTROLLER_KEY_DEVICE_OFFSET) | _subTrackerId); -} - - void ControllerScriptingInterface::emitKeyPressEvent(QKeyEvent* event) { emit keyPressEvent(KeyEvent(*event)); } void ControllerScriptingInterface::emitKeyReleaseEvent(QKeyEvent* event) { emit keyReleaseEvent(KeyEvent(*event)); } diff --git a/interface/src/scripting/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h index 996ccabb20..6d197477bb 100644 --- a/interface/src/scripting/ControllerScriptingInterface.h +++ b/interface/src/scripting/ControllerScriptingInterface.h @@ -25,38 +25,6 @@ #include class ScriptEngine; -class PalmData; - -class InputController : public controller::InputController { - Q_OBJECT - -public: - InputController(int deviceTrackerId, int subTrackerId, QObject* parent = NULL); - - virtual void update() override; - virtual Key getKey() const override; - -public slots: - - virtual bool isActive() const override { return _isActive; } - virtual glm::vec3 getAbsTranslation() const override { return _eventCache.absTranslation; } - virtual glm::quat getAbsRotation() const override { return _eventCache.absRotation; } - virtual glm::vec3 getLocTranslation() const override { return _eventCache.locTranslation; } - virtual glm::quat getLocRotation() const override { return _eventCache.locRotation; } - -private: - - int _deviceTrackerId; - uint _subTrackerId; - - // cache for the spatial - SpatialEvent _eventCache; - bool _isActive; - -signals: -}; - - /// handles scripting of input controller commands from JS class ControllerScriptingInterface : public controller::ScriptingInterface { Q_OBJECT @@ -86,8 +54,6 @@ public: bool isJoystickCaptured(int joystickIndex) const; bool areEntityClicksCaptured() const; - void updateInputControllers(); - public slots: virtual void captureKeyEvents(const KeyEvent& event); @@ -102,10 +68,6 @@ public slots: virtual glm::vec2 getViewportDimensions() const; virtual QVariant getRecommendedOverlayRect() const; - /// Factory to create an InputController - virtual controller::InputController* createInputController(const QString& deviceName, const QString& tracker); - virtual void releaseInputController(controller::InputController* input); - signals: void keyPressEvent(const KeyEvent& event); void keyReleaseEvent(const KeyEvent& event); @@ -135,8 +97,6 @@ private: bool _captureEntityClicks; using InputKey = controller::InputController::Key; - using InputControllerMap = std::map; - InputControllerMap _inputControllers; }; const int NUMBER_OF_SPATIALCONTROLS_PER_PALM = 2; // the hand and the tip diff --git a/libraries/trackers/src/trackers/DeviceTracker.cpp b/libraries/trackers/src/trackers/DeviceTracker.cpp deleted file mode 100644 index 93aeb607bc..0000000000 --- a/libraries/trackers/src/trackers/DeviceTracker.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// Created by Sam Cake on 6/20/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "DeviceTracker.h" - -DeviceTracker::SingletonData::~SingletonData() { - // Destroy all the device registered - //TODO C++11 for (auto device = _devicesVector.begin(); device != _devicesVector.end(); device++) { - for (Vector::iterator device = _devicesVector.begin(); device != _devicesVector.end(); device++) { - delete (*device); - } -} - -int DeviceTracker::getNumDevices() { - return (int)Singleton::get()->_devicesMap.size(); -} - -DeviceTracker::ID DeviceTracker::getDeviceID(const Name& name) { - //TODO C++11 auto deviceIt = Singleton::get()->_devicesMap.find(name); - Map::iterator deviceIt = Singleton::get()->_devicesMap.find(name); - if (deviceIt != Singleton::get()->_devicesMap.end()) { - return (*deviceIt).second; - } else { - return INVALID_DEVICE; - } -} - -DeviceTracker* DeviceTracker::getDevice(const Name& name) { - return getDevice(getDeviceID(name)); -} - -DeviceTracker* DeviceTracker::getDevice(DeviceTracker::ID deviceID) { - if ((deviceID >= 0) && (deviceID < (int)(Singleton::get()->_devicesVector.size()))) { - return Singleton::get()->_devicesVector[ deviceID ]; - } else { - return NULL; - } -} - -DeviceTracker::ID DeviceTracker::registerDevice(const Name& name, DeviceTracker* device) { - // Check that the device exists, if not exit - if (!device) { - return INVALID_DEVICE; - } - - // Look if the name is not already used - ID deviceID = getDeviceID(name); - if (deviceID >= 0) { - return INVALID_DEVICE_NAME; - } - - // Good to register the device - deviceID = (ID)Singleton::get()->_devicesVector.size(); - Singleton::get()->_devicesMap.insert(Map::value_type(name, deviceID)); - Singleton::get()->_devicesVector.push_back(device); - device->assignIDAndName(deviceID, name); - - return deviceID; -} - -void DeviceTracker::destroyDevice(const Name& name) { - DeviceTracker::ID deviceID = getDeviceID(name); - if (deviceID != INVALID_DEVICE) { - delete Singleton::get()->_devicesVector[getDeviceID(name)]; - Singleton::get()->_devicesVector[getDeviceID(name)] = nullptr; - } -} - -void DeviceTracker::updateAll() { - //TODO C++11 for (auto deviceIt = Singleton::get()->_devicesVector.begin(); deviceIt != Singleton::get()->_devicesVector.end(); deviceIt++) { - for (Vector::iterator deviceIt = Singleton::get()->_devicesVector.begin(); deviceIt != Singleton::get()->_devicesVector.end(); deviceIt++) { - if ((*deviceIt)) - (*deviceIt)->update(); - } -} - -// Core features of the Device Tracker -DeviceTracker::DeviceTracker() : - _ID(INVALID_DEVICE), - _name("Unkown") -{ -} - -DeviceTracker::~DeviceTracker() { -} - -void DeviceTracker::update() { -} diff --git a/libraries/trackers/src/trackers/DeviceTracker.h b/libraries/trackers/src/trackers/DeviceTracker.h deleted file mode 100644 index 8a7f509cb3..0000000000 --- a/libraries/trackers/src/trackers/DeviceTracker.h +++ /dev/null @@ -1,115 +0,0 @@ -// -// Created by Sam Cake on 6/20/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_DeviceTracker_h -#define hifi_DeviceTracker_h - -#include -#include -#include - -// Singleton template class -template < typename T > -class TemplateSingleton { -public: - - static T* get() { - if ( !_singleton._one ) { - _singleton._one = new T(); - } - return _singleton._one; - } - - TemplateSingleton() : - _one(0) - { - } - ~TemplateSingleton() { - if ( _one ) { - delete _one; - _one = 0; - } - } -private: - static TemplateSingleton< T > _singleton; - T* _one; -}; -template -TemplateSingleton TemplateSingleton::_singleton; - -/// Base class for device trackers. -class DeviceTracker { -public: - - // THe ID and Name types used to manage the pool of devices - typedef std::string Name; - typedef int ID; - static const ID INVALID_DEVICE = -1; - static const ID INVALID_DEVICE_NAME = -2; - - // Singleton interface to register and query the devices currently connected - static int getNumDevices(); - static ID getDeviceID(const Name& name); - static DeviceTracker* getDevice(ID deviceID); - static DeviceTracker* getDevice(const Name& name); - - /// Update all the devices calling for their update() function - /// This should be called every frame by the main loop to update all the devices that pull their state - static void updateAll(); - - /// Register a device tracker to the factory - /// Right after creating a new DeviceTracker, it should be registered - /// This is why, it's recommended to use a factory static call in the specialized class - /// to create a new input device - /// - /// \param name The Name under wich registering the device - /// \param parent The DeviceTracker - /// - /// \return The Index of the newly registered device. - /// Valid if everything went well. - /// INVALID_DEVICE if the device is not valid (NULL) - /// INVALID_DEVICE_NAME if the name is already taken - static ID registerDevice(const Name& name, DeviceTracker* tracker); - - static void destroyDevice(const Name& name); - - // DeviceTracker interface - - virtual void update(); - - /// Get the ID assigned to the Device when registered after creation, or INVALID_DEVICE if it hasn't been registered which should not happen. - ID getID() const { return _ID; } - - /// Get the name assigned to the Device when registered after creation, or "Unknown" if it hasn't been registered which should not happen. - const Name& getName() const { return _name; } - - typedef std::map< Name, ID > Map; - static const Map& getDevices() { return Singleton::get()->_devicesMap; } - -protected: - DeviceTracker(); - virtual ~DeviceTracker(); - -private: - ID _ID; - Name _name; - - // this call is used by the singleton when the device tracker is currently beeing registered and beeing assigned an ID - void assignIDAndName( const ID id, const Name& name ) { _ID = id; _name = name; } - - typedef std::vector< DeviceTracker* > Vector; - struct SingletonData { - Map _devicesMap; - Vector _devicesVector; - - ~SingletonData(); - }; - typedef TemplateSingleton< SingletonData > Singleton; -}; - -#endif // hifi_DeviceTracker_h diff --git a/libraries/trackers/src/trackers/MotionTracker.cpp b/libraries/trackers/src/trackers/MotionTracker.cpp deleted file mode 100644 index c6012c0422..0000000000 --- a/libraries/trackers/src/trackers/MotionTracker.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// -// Created by Sam Cake on 6/20/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "MotionTracker.h" - -// glm::mult(mat43, mat43) just the composition of the 2 matrices assuming they are in fact mat44 with the last raw = { 0, 0, 0, 1 } -namespace glm { - mat4x3 mult(const mat4& lhs, const mat4x3& rhs) { - vec3 lrx(lhs[0].x, lhs[1].x, lhs[2].x); - vec3 lry(lhs[0].y, lhs[1].y, lhs[2].y); - vec3 lrz(lhs[0].z, lhs[1].z, lhs[2].z); - return mat4x3( - dot(lrx, rhs[0]), - dot(lry, rhs[0]), - dot(lrz, rhs[0]), - - dot(lrx, rhs[1]), - dot(lry, rhs[1]), - dot(lrz, rhs[1]), - - dot(lrx, rhs[2]), - dot(lry, rhs[2]), - dot(lrz, rhs[2]), - - dot(lrx, rhs[3]) + lhs[3].x, - dot(lry, rhs[3]) + lhs[3].y, - dot(lrz, rhs[3]) + lhs[3].z - ); - } - mat4x3 mult(const mat4x3& lhs, const mat4x3& rhs) { - vec3 lrx(lhs[0].x, lhs[1].x, lhs[2].x); - vec3 lry(lhs[0].y, lhs[1].y, lhs[2].y); - vec3 lrz(lhs[0].z, lhs[1].z, lhs[2].z); - return mat4x3( - dot(lrx, rhs[0]), - dot(lry, rhs[0]), - dot(lrz, rhs[0]), - - dot(lrx, rhs[1]), - dot(lry, rhs[1]), - dot(lrz, rhs[1]), - - dot(lrx, rhs[2]), - dot(lry, rhs[2]), - dot(lrz, rhs[2]), - - dot(lrx, rhs[3]) + lhs[3].x, - dot(lry, rhs[3]) + lhs[3].y, - dot(lrz, rhs[3]) + lhs[3].z - ); - } -} - -// MotionTracker -MotionTracker::MotionTracker() : - DeviceTracker() -{ - _jointsArray.resize(1); - _jointsMap.insert(JointTracker::Map::value_type(Semantic("Root"), 0)); -} - -MotionTracker::~MotionTracker() -{ -} - -bool MotionTracker::isConnected() const { - return false; -} - -MotionTracker::Index MotionTracker::addJoint(const Semantic& semantic, Index parent) { - // Check the parent - if (int(parent) < 0) - return INVALID_PARENT; - - // Check that the semantic is not already in use - Index foundIndex = findJointIndex(semantic); - if (foundIndex >= 0) { - return INVALID_SEMANTIC; - } - - - // All good then allocate the joint - Index newIndex = (Index)_jointsArray.size(); - _jointsArray.push_back(JointTracker(semantic, parent)); - _jointsMap.insert(JointTracker::Map::value_type(semantic, newIndex)); - - return newIndex; -} - -MotionTracker::Index MotionTracker::findJointIndex(const Semantic& semantic) const { - // TODO C++11 auto jointIt = _jointsMap.find(semantic); - JointTracker::Map::const_iterator jointIt = _jointsMap.find(semantic); - if (jointIt != _jointsMap.end()) { - return (*jointIt).second; - } - - return INVALID_SEMANTIC; -} - -void MotionTracker::updateAllAbsTransform() { - _jointsArray[0].updateAbsFromLocTransform(0); - - // Because we know the hierarchy is stored from root down the branches let's just traverse and update - for (Index i = 1; i < (Index)(_jointsArray.size()); i++) { - JointTracker* joint = _jointsArray.data() + i; - joint->updateAbsFromLocTransform(_jointsArray.data() + joint->getParent()); - } -} - - -// MotionTracker::JointTracker -MotionTracker::JointTracker::JointTracker() : - _locFrame(), - _absFrame(), - _semantic(""), - _parent(INVALID_PARENT), - _lastUpdate(1) // Joint inactive -{ -} - -MotionTracker::JointTracker::JointTracker(const Semantic& semantic, Index parent) : - _semantic(semantic), - _parent(parent), - _lastUpdate(1) // Joint inactive -{ -} - -MotionTracker::JointTracker::JointTracker(const JointTracker& tracker) : - _locFrame(tracker._locFrame), - _absFrame(tracker._absFrame), - _semantic(tracker._semantic), - _parent(tracker._parent), - _lastUpdate(tracker._lastUpdate) -{ -} - -void MotionTracker::JointTracker::updateAbsFromLocTransform(const JointTracker* parentJoint) { - if (parentJoint) { - editAbsFrame()._transform = (parentJoint->getAbsFrame()._transform * getLocFrame()._transform); - } else { - editAbsFrame()._transform = getLocFrame()._transform; - } -} - -void MotionTracker::JointTracker::updateLocFromAbsTransform(const JointTracker* parentJoint) { - if (parentJoint) { - glm::mat4 ip = glm::inverse(parentJoint->getAbsFrame()._transform); - editLocFrame()._transform = (ip * getAbsFrame()._transform); - } else { - editLocFrame()._transform = getAbsFrame()._transform; - } -} - -//-------------------------------------------------------------------------------------- -// MotionTracker::Frame -//-------------------------------------------------------------------------------------- - -MotionTracker::Frame::Frame() : - _transform() -{ -} - -void MotionTracker::Frame::setRotation(const glm::quat& rotation) { - glm::mat3x3 rot = glm::mat3_cast(rotation); - _transform[0] = glm::vec4(rot[0], 0.0f); - _transform[1] = glm::vec4(rot[1], 0.0f); - _transform[2] = glm::vec4(rot[2], 0.0f); -} - -void MotionTracker::Frame::getRotation(glm::quat& rotation) const { - rotation = glm::quat_cast(_transform); -} - -void MotionTracker::Frame::setTranslation(const glm::vec3& translation) { - _transform[3] = glm::vec4(translation, 1.0f); -} - -void MotionTracker::Frame::getTranslation(glm::vec3& translation) const { - translation = extractTranslation(_transform); -} - diff --git a/libraries/trackers/src/trackers/MotionTracker.h b/libraries/trackers/src/trackers/MotionTracker.h deleted file mode 100644 index 26c8dcea2c..0000000000 --- a/libraries/trackers/src/trackers/MotionTracker.h +++ /dev/null @@ -1,116 +0,0 @@ -// -// Created by Sam Cake on 6/20/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_MotionTracker_h -#define hifi_MotionTracker_h - -#include "DeviceTracker.h" - -#include - -/// Base class for device trackers. -class MotionTracker : public DeviceTracker { -public: - - class Frame { - public: - Frame(); - - glm::mat4 _transform; - - void setRotation(const glm::quat& rotation); - void getRotation(glm::quat& rotatio) const; - - void setTranslation(const glm::vec3& translation); - void getTranslation(glm::vec3& translation) const; - }; - - // Semantic and Index types to retreive the JointTrackers of this MotionTracker - typedef std::string Semantic; - typedef int32_t Index; - static const Index INVALID_SEMANTIC = -1; - static const Index INVALID_PARENT = -2; - - class JointTracker { - public: - typedef std::vector< JointTracker > Vector; - typedef std::map< Semantic, Index > Map; - - JointTracker(); - JointTracker(const JointTracker& tracker); - JointTracker(const Semantic& semantic, Index parent); - - const Frame& getLocFrame() const { return _locFrame; } - Frame& editLocFrame() { return _locFrame; } - void setLocFrame(const Frame& frame) { editLocFrame() = frame; } - - const Frame& getAbsFrame() const { return _absFrame; } - Frame& editAbsFrame() { return _absFrame; } - void setAbsFrame(const Frame& frame) { editAbsFrame() = frame; } - - const Semantic& getSemantic() const { return _semantic; } - const Index& getParent() const { return _parent; } - - bool isActive() const { return (_lastUpdate <= 0); } - void tickNewFrame() { _lastUpdate++; } - void activeFrame() { _lastUpdate = 0; } - - /// Update the loc/abs transform for this joint from the current abs/loc value and the specified parent joint abs frame - void updateLocFromAbsTransform(const JointTracker* parentJoint); - void updateAbsFromLocTransform(const JointTracker* parentJoint); - - protected: - Frame _locFrame; - Frame _absFrame; - Semantic _semantic; - Index _parent; - int _lastUpdate; - }; - - virtual bool isConnected() const; - - Index numJointTrackers() const { return (Index)_jointsArray.size(); } - - /// Access a Joint from it's index. - /// Index 0 is always the "Root". - /// if the index is Invalid then returns NULL. - const JointTracker* getJointTracker(Index index) const { return ((index > 0) && (index < (Index)(_jointsArray.size())) ? _jointsArray.data() + index : NULL); } - JointTracker* editJointTracker(Index index) { return ((index > 0) && (index < (Index)(_jointsArray.size())) ? _jointsArray.data() + index : NULL); } - - /// From a semantic, find the Index of the Joint. - /// \return the index of the mapped Joint or INVALID_SEMANTIC if the semantic is not knowned. - Index findJointIndex(const Semantic& semantic) const; - -protected: - MotionTracker(); - virtual ~MotionTracker(); - - JointTracker::Vector _jointsArray; - JointTracker::Map _jointsMap; - - /// Adding joint is only done from the specialized Motion Tracker, hence this function is protected. - /// The hierarchy of joints must be created from the top down to the branches. - /// The "Root" node is at index 0 and exists at creation of the Motion Tracker. - /// - /// \param semantic A joint is defined by it's semantic, the unique name mapping to it - /// \param parent The parent's index, the parent must be valid and correspond to a Joint that has been previously created - /// - /// \return The Index of the newly created Joint. - /// Valid if everything went well. - /// INVALID_SEMANTIC if the semantic is already in use - /// INVALID_PARENT if the parent is not valid - Index addJoint(const Semantic& semantic, Index parent); - - /// Update the absolute transform stack traversing the hierarchy from the root down the branches - /// This is a generic way to update all the Joint's absFrame by combining the locFrame going down the hierarchy branch. - void updateAllAbsTransform(); -}; - - - -#endif // hifi_MotionTracker_h diff --git a/scripts/system/controllers/leapHands.js b/scripts/system/controllers/leapHands.js deleted file mode 100644 index 1be0b1e5f6..0000000000 --- a/scripts/system/controllers/leapHands.js +++ /dev/null @@ -1,527 +0,0 @@ -// -// leapHands.js -// examples -// -// Created by David Rowe on 8 Sep 2014. -// Copyright 2014 High Fidelity, Inc. -// -// This is an example script that uses the Leap Motion to make the avatar's hands replicate the user's hand actions. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -var leftTriggerValue = 0; -var rightTriggerValue = 0; - -var LEAP_TRIGGER_START_ANGLE = 15.0; -var LEAP_TRIGGER_END_ANGLE = 40.0; - -function getLeapMotionLeftTrigger() { - //print("left trigger = " + leftTriggerValue); - return leftTriggerValue; -} -function getLeapMotionRightTrigger() { - //print("right trigger = " + rightTriggerValue); - return rightTriggerValue; -} - -var leapHands = (function () { - - var isOnHMD, - LEAP_ON_HMD_MENU_ITEM = "Leap Motion on HMD", - LEAP_OFFSET = 0.019, // Thickness of Leap Motion plus HMD clip - HMD_OFFSET = 0.070, // Eyeballs to front surface of Oculus DK2 TODO: Confirm and make depend on device and eye relief - hasHandAndWristJoints, - handToWristOffset = [], // For avatars without a wrist joint we control an estimate of a proper hand joint position - HAND_OFFSET = 0.4, // Relative distance of wrist to hand versus wrist to index finger knuckle - handAnimationStateHandlers, - handAnimationStateFunctions, - handAnimationStateProperties, - hands, - wrists, - NUM_HANDS = 2, // 0 = left; 1 = right - fingers, - NUM_FINGERS = 5, // 0 = thumb; ...; 4 = pinky - THUMB = 0, - MIDDLE_FINGER = 2, - NUM_FINGER_JOINTS = 3, // 0 = metacarpal(hand)-proximal(finger) joint; ...; 2 = intermediate-distal joint - MAX_HAND_INACTIVE_COUNT = 20, - calibrationStatus, - UNCALIBRATED = 0, - CALIBRATING = 1, - CALIBRATED = 2, - CALIBRATION_TIME = 1000, // milliseconds - avatarScale, - avatarFaceModelURL, - avatarSkeletonModelURL, - settingsTimer, - HMD_CAMERA_TO_AVATAR_ROTATION = [ - Quat.angleAxis(180.0, { x: 0, y: 0, z: 1 }), - Quat.angleAxis(-180.0, { x: 0, y: 0, z: 1 }) - ], - DESKTOP_CAMERA_TO_AVATAR_ROTATION = - Quat.multiply(Quat.angleAxis(180.0, { x: 0, y: 1, z: 0 }), Quat.angleAxis(90.0, { x: 0, y: 0, z: 1 })), - LEAP_THUMB_ROOT_ADJUST = [Quat.fromPitchYawRollDegrees(0, 0, 20), Quat.fromPitchYawRollDegrees(0, 0, -20)]; - - function printSkeletonJointNames() { - var jointNames, - i; - - print(MyAvatar.skeletonModelURL); - - print("Skeleton joint names ..."); - jointNames = MyAvatar.getJointNames(); - for (i = 0; i < jointNames.length; i += 1) { - print(i + ": " + jointNames[i]); - } - print("... skeleton joint names"); - } - - function animateLeftHand() { - var ROTATION_AND_POSITION = 0; - - return { - leftHandType: ROTATION_AND_POSITION, - leftHandPosition: hands[0].position, - leftHandRotation: hands[0].rotation - }; - } - - function animateRightHand() { - var ROTATION_AND_POSITION = 0; - - return { - rightHandType: ROTATION_AND_POSITION, - rightHandPosition: hands[1].position, - rightHandRotation: hands[1].rotation - }; - } - - function finishCalibration() { - var avatarPosition, - handPosition, - middleFingerPosition, - leapHandHeight, - h; - - if (!isOnHMD) { - if (hands[0].controller.isActive() && hands[1].controller.isActive()) { - leapHandHeight = (hands[0].controller.getAbsTranslation().y + hands[1].controller.getAbsTranslation().y) / 2.0; - } else { - calibrationStatus = UNCALIBRATED; - return; - } - } - - avatarPosition = MyAvatar.position; - - for (h = 0; h < NUM_HANDS; h += 1) { - handPosition = MyAvatar.getJointPosition(hands[h].jointName); - if (!hasHandAndWristJoints) { - middleFingerPosition = MyAvatar.getJointPosition(fingers[h][MIDDLE_FINGER][0].jointName); - handToWristOffset[h] = Vec3.multiply(Vec3.subtract(handPosition, middleFingerPosition), 1.0 - HAND_OFFSET); - } - - if (isOnHMD) { - // Offset of Leap Motion origin from physical eye position - hands[h].zeroPosition = { x: 0.0, y: 0.0, z: HMD_OFFSET + LEAP_OFFSET }; - } else { - hands[h].zeroPosition = { - x: handPosition.x - avatarPosition.x, - y: handPosition.y - avatarPosition.y, - z: avatarPosition.z - handPosition.z - }; - hands[h].zeroPosition = Vec3.multiplyQbyV(MyAvatar.orientation, hands[h].zeroPosition); - hands[h].zeroPosition.y = hands[h].zeroPosition.y - leapHandHeight; - } - } - - MyAvatar.clearJointData("LeftHand"); - MyAvatar.clearJointData("LeftForeArm"); - MyAvatar.clearJointData("RightHand"); - MyAvatar.clearJointData("RightForeArm"); - - calibrationStatus = CALIBRATED; - print("Leap Motion: Calibrated"); - } - - function calibrate() { - var jointNames, - i; - - calibrationStatus = CALIBRATING; - - avatarScale = MyAvatar.scale; - avatarFaceModelURL = MyAvatar.faceModelURL; - avatarSkeletonModelURL = MyAvatar.skeletonModelURL; - - // Does this skeleton have both wrist and hand joints? - hasHandAndWristJoints = false; - jointNames = MyAvatar.getJointNames(); - for (i = 0; i < jointNames.length; i += 1) { - hasHandAndWristJoints = hasHandAndWristJoints || jointNames[i].toLowerCase() === "leftwrist"; - } - - // Set avatar arms vertical, forearms horizontal, as "zero" position for calibration - MyAvatar.setJointRotation("LeftForeArm", Quat.fromPitchYawRollDegrees(0.0, 0.0, 90.0)); - MyAvatar.setJointRotation("LeftHand", Quat.fromPitchYawRollDegrees(0.0, 90.0, 0.0)); - MyAvatar.setJointRotation("RightForeArm", Quat.fromPitchYawRollDegrees(0.0, 0.0, -90.0)); - MyAvatar.setJointRotation("RightHand", Quat.fromPitchYawRollDegrees(0.0, -90.0, 0.0)); - - // Wait for arms to assume their positions before calculating - Script.setTimeout(finishCalibration, CALIBRATION_TIME); - } - - function checkCalibration() { - - if (calibrationStatus === CALIBRATED) { - return true; - } - - if (calibrationStatus !== CALIBRATING) { - calibrate(); - } - - return false; - } - - function setIsOnHMD() { - isOnHMD = Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM); - print("Leap Motion: " + (isOnHMD ? "Is on HMD" : "Is on desk")); - } - - function checkSettings() { - if (calibrationStatus > UNCALIBRATED && (MyAvatar.scale !== avatarScale - || MyAvatar.faceModelURL !== avatarFaceModelURL - || MyAvatar.skeletonModelURL !== avatarSkeletonModelURL - || Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM) !== isOnHMD)) { - print("Leap Motion: Recalibrate..."); - calibrationStatus = UNCALIBRATED; - - setIsOnHMD(); - } - } - - function setUp() { - - wrists = [ - { - jointName: "LeftWrist", - controller: Controller.createInputController("Spatial", "joint_L_wrist") - }, - { - jointName: "RightWrist", - controller: Controller.createInputController("Spatial", "joint_R_wrist") - } - ]; - - hands = [ - { - jointName: "LeftHand", - controller: Controller.createInputController("Spatial", "joint_L_hand"), - inactiveCount: 0 - }, - { - jointName: "RightHand", - controller: Controller.createInputController("Spatial", "joint_R_hand"), - inactiveCount: 0 - } - ]; - - // The Leap controller's first joint is the hand-metacarpal joint but this joint's data is not used because it's too - // dependent on the model skeleton exactly matching the Leap skeleton; using just the second and subsequent joints - // seems to work better over all. - fingers = [{}, {}]; - fingers[0] = [ - [ - { jointName: "LeftHandThumb1", controller: Controller.createInputController("Spatial", "joint_L_thumb2") }, - { jointName: "LeftHandThumb2", controller: Controller.createInputController("Spatial", "joint_L_thumb3") }, - { jointName: "LeftHandThumb3", controller: Controller.createInputController("Spatial", "joint_L_thumb4") } - ], - [ - { jointName: "LeftHandIndex1", controller: Controller.createInputController("Spatial", "joint_L_index2") }, - { jointName: "LeftHandIndex2", controller: Controller.createInputController("Spatial", "joint_L_index3") }, - { jointName: "LeftHandIndex3", controller: Controller.createInputController("Spatial", "joint_L_index4") } - ], - [ - { jointName: "LeftHandMiddle1", controller: Controller.createInputController("Spatial", "joint_L_middle2") }, - { jointName: "LeftHandMiddle2", controller: Controller.createInputController("Spatial", "joint_L_middle3") }, - { jointName: "LeftHandMiddle3", controller: Controller.createInputController("Spatial", "joint_L_middle4") } - ], - [ - { jointName: "LeftHandRing1", controller: Controller.createInputController("Spatial", "joint_L_ring2") }, - { jointName: "LeftHandRing2", controller: Controller.createInputController("Spatial", "joint_L_ring3") }, - { jointName: "LeftHandRing3", controller: Controller.createInputController("Spatial", "joint_L_ring4") } - ], - [ - { jointName: "LeftHandPinky1", controller: Controller.createInputController("Spatial", "joint_L_pinky2") }, - { jointName: "LeftHandPinky2", controller: Controller.createInputController("Spatial", "joint_L_pinky3") }, - { jointName: "LeftHandPinky3", controller: Controller.createInputController("Spatial", "joint_L_pinky4") } - ] - ]; - fingers[1] = [ - [ - { jointName: "RightHandThumb1", controller: Controller.createInputController("Spatial", "joint_R_thumb2") }, - { jointName: "RightHandThumb2", controller: Controller.createInputController("Spatial", "joint_R_thumb3") }, - { jointName: "RightHandThumb3", controller: Controller.createInputController("Spatial", "joint_R_thumb4") } - ], - [ - { jointName: "RightHandIndex1", controller: Controller.createInputController("Spatial", "joint_R_index2") }, - { jointName: "RightHandIndex2", controller: Controller.createInputController("Spatial", "joint_R_index3") }, - { jointName: "RightHandIndex3", controller: Controller.createInputController("Spatial", "joint_R_index4") } - ], - [ - { jointName: "RightHandMiddle1", controller: Controller.createInputController("Spatial", "joint_R_middle2") }, - { jointName: "RightHandMiddle2", controller: Controller.createInputController("Spatial", "joint_R_middle3") }, - { jointName: "RightHandMiddle3", controller: Controller.createInputController("Spatial", "joint_R_middle4") } - ], - [ - { jointName: "RightHandRing1", controller: Controller.createInputController("Spatial", "joint_R_ring2") }, - { jointName: "RightHandRing2", controller: Controller.createInputController("Spatial", "joint_R_ring3") }, - { jointName: "RightHandRing3", controller: Controller.createInputController("Spatial", "joint_R_ring4") } - ], - [ - { jointName: "RightHandPinky1", controller: Controller.createInputController("Spatial", "joint_R_pinky2") }, - { jointName: "RightHandPinky2", controller: Controller.createInputController("Spatial", "joint_R_pinky3") }, - { jointName: "RightHandPinky3", controller: Controller.createInputController("Spatial", "joint_R_pinky4") } - ] - ]; - - handAnimationStateHandlers = [null, null]; - handAnimationStateFunctions = [animateLeftHand, animateRightHand]; - handAnimationStateProperties = [ - ["leftHandType", "leftHandPosition", "leftHandRotation"], - ["rightHandType", "rightHandPosition", "rightHandPosition"] - ]; - - setIsOnHMD(); - - settingsTimer = Script.setInterval(checkSettings, 2000); - - calibrationStatus = UNCALIBRATED; - - { - var mapping = Controller.newMapping("LeapmotionTrigger"); - mapping.from(getLeapMotionLeftTrigger).to(Controller.Standard.LT); - mapping.from(getLeapMotionRightTrigger).to(Controller.Standard.RT); - mapping.enable(); - } - } - - function moveHands() { - var h, - i, - j, - side, - handOffset, - wristOffset, - handRotation, - locRotation, - cameraOrientation, - inverseAvatarOrientation; - - for (h = 0; h < NUM_HANDS; h += 1) { - side = h === 0 ? -1.0 : 1.0; - - if (hands[h].controller.isActive()) { - - // Calibrate if necessary. - if (!checkCalibration()) { - return; - } - - // Hand animation handlers ... - if (handAnimationStateHandlers[h] === null) { - handAnimationStateHandlers[h] = MyAvatar.addAnimationStateHandler(handAnimationStateFunctions[h], - handAnimationStateProperties[h]); - } - - // Hand position ... - handOffset = hands[h].controller.getAbsTranslation(); - handRotation = hands[h].controller.getAbsRotation(); - - if (isOnHMD) { - - // Adjust to control wrist position if "hand" joint is at wrist ... - if (!hasHandAndWristJoints) { - wristOffset = Vec3.multiplyQbyV(handRotation, handToWristOffset[h]); - handOffset = Vec3.sum(handOffset, wristOffset); - } - - // Hand offset in camera coordinates ... - handOffset = { - x: -handOffset.x, - y: -handOffset.z, - z: -handOffset.y - hands[h].zeroPosition.z - }; - - // Hand offset in world coordinates ... - cameraOrientation = Camera.getOrientation(); - handOffset = Vec3.sum(Camera.getPosition(), Vec3.multiplyQbyV(cameraOrientation, handOffset)); - - // Hand offset in avatar coordinates ... - inverseAvatarOrientation = Quat.inverse(MyAvatar.orientation); - handOffset = Vec3.subtract(handOffset, MyAvatar.position); - handOffset = Vec3.multiplyQbyV(inverseAvatarOrientation, handOffset); - handOffset.z = -handOffset.z; - handOffset.x = -handOffset.x; - - - // Hand rotation in camera coordinates ... - handRotation = { - x: -handRotation.y, - y: -handRotation.z, - z: -handRotation.x, - w: handRotation.w - }; - - // Hand rotation in avatar coordinates ... - handRotation = Quat.multiply(HMD_CAMERA_TO_AVATAR_ROTATION[h], handRotation); - cameraOrientation = { - x: cameraOrientation.z, - y: cameraOrientation.y, - z: cameraOrientation.x, - w: cameraOrientation.w - }; - cameraOrientation = Quat.multiply(cameraOrientation, Quat.inverse(MyAvatar.orientation)); - handRotation = Quat.multiply(handRotation, cameraOrientation); // Works!!! - - } else { - - // Adjust to control wrist position if "hand" joint is at wrist ... - if (!hasHandAndWristJoints) { - wristOffset = Vec3.multiplyQbyV(handRotation, handToWristOffset[h]); - handOffset = Vec3.sum(handOffset, wristOffset); - } - - // Hand offset in camera coordinates ... - handOffset = { - x: -handOffset.x, - y: hands[h].zeroPosition.y + handOffset.y, - z: hands[h].zeroPosition.z - handOffset.z - }; - - // Hand rotation in camera coordinates ... - handRotation = { - x: handRotation.z, - y: handRotation.y, - z: handRotation.x, - w: handRotation.w - }; - - // Hand rotation in avatar coordinates ... - handRotation = Quat.multiply(DESKTOP_CAMERA_TO_AVATAR_ROTATION, handRotation); - } - - // Set hand position and orientation for animation state handler ... - hands[h].position = handOffset; - hands[h].rotation = handRotation; - - // Set finger joints ... - var summed = 0; - var closeAngle = 0; - for (i = 0; i < NUM_FINGERS; i += 1) { - for (j = 0; j < NUM_FINGER_JOINTS; j += 1) { - if (fingers[h][i][j].controller !== null) { - locRotation = fingers[h][i][j].controller.getLocRotation(); - var eulers = Quat.safeEulerAngles(locRotation); - closeAngle += eulers.x; - - summed++; - - if (i === THUMB) { - locRotation = { - x: side * locRotation.y, - y: side * -locRotation.z, - z: side * -locRotation.x, - w: locRotation.w - }; - if (j === 0) { - // Adjust avatar thumb root joint rotation to make avatar hands look better - locRotation = Quat.multiply(LEAP_THUMB_ROOT_ADJUST[h], locRotation); - } - } else { - locRotation = { - x: -locRotation.x, - y: -locRotation.z, - z: -locRotation.y, - w: locRotation.w - }; - } - MyAvatar.setJointRotation(fingers[h][i][j].jointName, locRotation); - } - } - } - - hands[h].inactiveCount = 0; - if (summed > 0) { - closeAngle /= summed; - } - - var triggerValue = (-closeAngle - LEAP_TRIGGER_START_ANGLE) / (LEAP_TRIGGER_END_ANGLE - LEAP_TRIGGER_START_ANGLE); - triggerValue = Math.max(0.0, Math.min(triggerValue, 1.0)); - - if (h == 0) { - leftTriggerValue = triggerValue; - } else { - rightTriggerValue = triggerValue; - - } - - } else { - - if (hands[h].inactiveCount < MAX_HAND_INACTIVE_COUNT) { - - hands[h].inactiveCount += 1; - - if (hands[h].inactiveCount === MAX_HAND_INACTIVE_COUNT) { - if (handAnimationStateHandlers[h] !== null) { - MyAvatar.removeAnimationStateHandler(handAnimationStateHandlers[h]); - handAnimationStateHandlers[h] = null; - leftTriggerValue = 0.0; - rightTriggerValue = 0.0; - } - } - } - } - } - } - - function tearDown() { - var h, - i, - j; - - Script.clearInterval(settingsTimer); - - for (h = 0; h < NUM_HANDS; h += 1) { - Controller.releaseInputController(hands[h].controller); - Controller.releaseInputController(wrists[h].controller); - if (handAnimationStateHandlers[h] !== null) { - MyAvatar.removeAnimationStateHandler(handAnimationStateHandlers[h]); - } - for (i = 0; i < NUM_FINGERS; i += 1) { - for (j = 0; j < NUM_FINGER_JOINTS; j += 1) { - if (fingers[h][i][j].controller !== null) { - Controller.releaseInputController(fingers[h][i][j].controller); - } - } - } - } - } - - return { - printSkeletonJointNames: printSkeletonJointNames, - setUp : setUp, - moveHands : moveHands, - tearDown : tearDown - }; -}()); - - -//leapHands.printSkeletonJointNames(); - -leapHands.setUp(); -Script.update.connect(leapHands.moveHands); -Script.scriptEnding.connect(leapHands.tearDown);