From 2501be16cbc3bf5760699b1d1e7f8562da82526b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 1 Feb 2016 18:11:27 -0800 Subject: [PATCH] base palm position on finger joint rather than an offset from hand joint. double size of near-grab sphere --- examples/controllers/handControllerGrab.js | 42 ++++++++++++++++++++-- interface/src/avatar/Avatar.cpp | 12 +++++-- interface/src/avatar/SkeletonModel.cpp | 16 +++++++++ interface/src/avatar/SkeletonModel.h | 3 ++ 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 074b72c9f4..3695c6c3f8 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -69,13 +69,14 @@ var PICK_MAX_DISTANCE = 500; // max length of pick-ray // near grabbing // -var GRAB_RADIUS = 0.03; // if the ray misses but an object is this close, it will still be selected +var GRAB_RADIUS = 0.06; // if the ray misses but an object is this close, it will still be selected var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable. var NEAR_PICK_MAX_DISTANCE = 0.3; // max length of pick-ray for close grabbing to be selected var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object var NEAR_GRABBING_KINEMATIC = true; // force objects to be kinematic when near-grabbed +var SHOW_GRAB_SPHERE = false; // draw a green sphere to show the grab search position and size // // equip @@ -256,6 +257,7 @@ function MyController(hand) { //for visualizations this.overlayLine = null; this.particleBeamObject = null; + this.grabSphere = null; //for lights this.spotlight = null; @@ -336,6 +338,7 @@ function MyController(hand) { } this.setState = function(newState) { + this.grabSphereOff(); if (WANT_DEBUG || WANT_DEBUG_STATE) { print("STATE (" + this.hand + "): " + stateToName(this.state) + " --> " + stateToName(newState) + ", hand: " + this.hand); @@ -416,6 +419,37 @@ function MyController(hand) { } } + this.grabSphereOn = function() { + var color = {red: 0, green: 255, blue: 0}; + if (this.grabSphere === null) { + var sphereProperties = { + position: this.getHandPosition(), + size: GRAB_RADIUS*2, + color: color, + alpha: 0.1, + solid: true, + visible: true + } + this.grabSphere = Overlays.addOverlay("sphere", sphereProperties); + } else { + Overlays.editOverlay(this.grabSphere, { + position: this.getHandPosition(), + size: GRAB_RADIUS*2, + color: color, + alpha: 0.1, + solid: true, + visible: true + }); + } + } + + this.grabSphereOff = function() { + if (this.grabSphere !== null) { + Overlays.deleteOverlay(this.grabSphere); + this.grabSphere = null; + } + }; + this.overlayLineOn = function(closePoint, farPoint, color) { if (this.overlayLine === null) { var lineProperties = { @@ -644,7 +678,6 @@ function MyController(hand) { this.searchSphereDistance = DEFAULT_SEARCH_SPHERE_DISTANCE; this.intersectionDistance = 0.0; } - }; this.particleBeamOff = function() { @@ -749,6 +782,11 @@ function MyController(hand) { // the trigger is being pressed, so do a ray test to see what we are hitting var handPosition = this.getHandPosition(); + + if (SHOW_GRAB_SPHERE) { + this.grabSphereOn(); + } + var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation; var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation)); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index a552b77f1f..786e409d92 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -1132,8 +1132,12 @@ glm::quat Avatar::getRightPalmRotation() const { glm::vec3 Avatar::getUncachedLeftPalmPosition() const { assert(QThread::currentThread() == thread()); // main thread access only glm::quat leftPalmRotation; - getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftPalmRotation); glm::vec3 leftPalmPosition; + if (_skeletonModel.getLeftGrabPosition(leftPalmPosition)) { + return leftPalmPosition; + } + // avatar didn't have a LeftHandMiddle1 joint, fall back on this: + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftPalmRotation); getSkeletonModel().getLeftHandPosition(leftPalmPosition); leftPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftPalmRotation); return leftPalmPosition; @@ -1149,8 +1153,12 @@ glm::quat Avatar::getUncachedLeftPalmRotation() const { glm::vec3 Avatar::getUncachedRightPalmPosition() const { assert(QThread::currentThread() == thread()); // main thread access only glm::quat rightPalmRotation; - getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightPalmRotation); glm::vec3 rightPalmPosition; + if (_skeletonModel.getRightGrabPosition(rightPalmPosition)) { + return rightPalmPosition; + } + // avatar didn't have a RightHandMiddle1 joint, fall back on this: + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightPalmRotation); getSkeletonModel().getRightHandPosition(rightPalmPosition); rightPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightPalmRotation); return rightPalmPosition; diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 6198a1b0a0..7a871236c5 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -235,6 +235,22 @@ void SkeletonModel::applyPalmData(int jointIndex, const PalmData& palm) { } } +bool SkeletonModel::getLeftGrabPosition(glm::vec3& position) const { + int index = _rig->indexOfJoint("LeftHandMiddle1"); + if (index >= 0) { + return getJointPositionInWorldFrame(index, position); + } + return false; +} + +bool SkeletonModel::getRightGrabPosition(glm::vec3& position) const { + int index = _rig->indexOfJoint("RightHandMiddle1"); + if (index >= 0) { + return getJointPositionInWorldFrame(index, position); + } + return false; +} + bool SkeletonModel::getLeftHandPosition(glm::vec3& position) const { return getJointPositionInWorldFrame(getLeftHandJointIndex(), position); } diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index 7541a002dc..b57d54020d 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -39,6 +39,9 @@ public: /// Returns the index of the right hand joint, or -1 if not found. int getRightHandJointIndex() const { return isActive() ? _geometry->getFBXGeometry().rightHandJointIndex : -1; } + bool getLeftGrabPosition(glm::vec3& position) const; + bool getRightGrabPosition(glm::vec3& position) const; + /// Retrieve the position of the left hand /// \return true whether or not the position was found bool getLeftHandPosition(glm::vec3& position) const;