mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 13:28:09 +02:00
Merge pull request #7012 from sethalves/adjust-palm-position
base palm position on finger joint rather than an offset from hand joint
This commit is contained in:
commit
cd56d635e1
4 changed files with 103 additions and 4 deletions
|
@ -69,13 +69,14 @@ var PICK_MAX_DISTANCE = 500; // max length of pick-ray
|
||||||
// near grabbing
|
// 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_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_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 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 RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things
|
||||||
var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object
|
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 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
|
// equip
|
||||||
|
@ -256,6 +257,7 @@ function MyController(hand) {
|
||||||
//for visualizations
|
//for visualizations
|
||||||
this.overlayLine = null;
|
this.overlayLine = null;
|
||||||
this.particleBeamObject = null;
|
this.particleBeamObject = null;
|
||||||
|
this.grabSphere = null;
|
||||||
|
|
||||||
//for lights
|
//for lights
|
||||||
this.spotlight = null;
|
this.spotlight = null;
|
||||||
|
@ -336,6 +338,7 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState = function(newState) {
|
this.setState = function(newState) {
|
||||||
|
this.grabSphereOff();
|
||||||
if (WANT_DEBUG || WANT_DEBUG_STATE) {
|
if (WANT_DEBUG || WANT_DEBUG_STATE) {
|
||||||
print("STATE (" + this.hand + "): " + stateToName(this.state) + " --> " +
|
print("STATE (" + this.hand + "): " + stateToName(this.state) + " --> " +
|
||||||
stateToName(newState) + ", hand: " + this.hand);
|
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) {
|
this.overlayLineOn = function(closePoint, farPoint, color) {
|
||||||
if (this.overlayLine === null) {
|
if (this.overlayLine === null) {
|
||||||
var lineProperties = {
|
var lineProperties = {
|
||||||
|
@ -644,7 +678,6 @@ function MyController(hand) {
|
||||||
this.searchSphereDistance = DEFAULT_SEARCH_SPHERE_DISTANCE;
|
this.searchSphereDistance = DEFAULT_SEARCH_SPHERE_DISTANCE;
|
||||||
this.intersectionDistance = 0.0;
|
this.intersectionDistance = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.particleBeamOff = function() {
|
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
|
// the trigger is being pressed, so do a ray test to see what we are hitting
|
||||||
var handPosition = this.getHandPosition();
|
var handPosition = this.getHandPosition();
|
||||||
|
|
||||||
|
if (SHOW_GRAB_SPHERE) {
|
||||||
|
this.grabSphereOn();
|
||||||
|
}
|
||||||
|
|
||||||
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||||
var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation;
|
var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation;
|
||||||
var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation));
|
var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation));
|
||||||
|
|
|
@ -1132,8 +1132,12 @@ glm::quat Avatar::getRightPalmRotation() const {
|
||||||
glm::vec3 Avatar::getUncachedLeftPalmPosition() const {
|
glm::vec3 Avatar::getUncachedLeftPalmPosition() const {
|
||||||
assert(QThread::currentThread() == thread()); // main thread access only
|
assert(QThread::currentThread() == thread()); // main thread access only
|
||||||
glm::quat leftPalmRotation;
|
glm::quat leftPalmRotation;
|
||||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftPalmRotation);
|
|
||||||
glm::vec3 leftPalmPosition;
|
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);
|
getSkeletonModel().getLeftHandPosition(leftPalmPosition);
|
||||||
leftPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftPalmRotation);
|
leftPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftPalmRotation);
|
||||||
return leftPalmPosition;
|
return leftPalmPosition;
|
||||||
|
@ -1149,8 +1153,12 @@ glm::quat Avatar::getUncachedLeftPalmRotation() const {
|
||||||
glm::vec3 Avatar::getUncachedRightPalmPosition() const {
|
glm::vec3 Avatar::getUncachedRightPalmPosition() const {
|
||||||
assert(QThread::currentThread() == thread()); // main thread access only
|
assert(QThread::currentThread() == thread()); // main thread access only
|
||||||
glm::quat rightPalmRotation;
|
glm::quat rightPalmRotation;
|
||||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightPalmRotation);
|
|
||||||
glm::vec3 rightPalmPosition;
|
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);
|
getSkeletonModel().getRightHandPosition(rightPalmPosition);
|
||||||
rightPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightPalmRotation);
|
rightPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightPalmRotation);
|
||||||
return rightPalmPosition;
|
return rightPalmPosition;
|
||||||
|
|
|
@ -235,6 +235,56 @@ void SkeletonModel::applyPalmData(int jointIndex, const PalmData& palm) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SkeletonModel::getLeftGrabPosition(glm::vec3& position) const {
|
||||||
|
int knuckleIndex = _rig->indexOfJoint("LeftHandMiddle1");
|
||||||
|
int handIndex = _rig->indexOfJoint("LeftHand");
|
||||||
|
if (knuckleIndex >= 0 && handIndex >= 0) {
|
||||||
|
glm::quat handRotation;
|
||||||
|
glm::vec3 knucklePosition;
|
||||||
|
glm::vec3 handPosition;
|
||||||
|
if (!getJointPositionInWorldFrame(knuckleIndex, knucklePosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getJointPositionInWorldFrame(handIndex, handPosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getJointRotationInWorldFrame(handIndex, handRotation)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
float halfPalmLength = glm::distance(knucklePosition, handPosition) * 0.5f;
|
||||||
|
// z azis is standardized to be out of the palm. move from the knuckle-joint away from the palm
|
||||||
|
// by 1/2 the palm length.
|
||||||
|
position = knucklePosition + handRotation * (glm::vec3(0.0f, 0.0f, 1.0f) * halfPalmLength);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SkeletonModel::getRightGrabPosition(glm::vec3& position) const {
|
||||||
|
int knuckleIndex = _rig->indexOfJoint("RightHandMiddle1");
|
||||||
|
int handIndex = _rig->indexOfJoint("RightHand");
|
||||||
|
if (knuckleIndex >= 0 && handIndex >= 0) {
|
||||||
|
glm::quat handRotation;
|
||||||
|
glm::vec3 knucklePosition;
|
||||||
|
glm::vec3 handPosition;
|
||||||
|
if (!getJointPositionInWorldFrame(knuckleIndex, knucklePosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getJointPositionInWorldFrame(handIndex, handPosition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getJointRotationInWorldFrame(handIndex, handRotation)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
float halfPalmLength = glm::distance(knucklePosition, handPosition) * 0.5f;
|
||||||
|
// z azis is standardized to be out of the palm. move from the knuckle-joint away from the palm
|
||||||
|
// by 1/2 the palm length.
|
||||||
|
position = knucklePosition + handRotation * (glm::vec3(0.0f, 0.0f, 1.0f) * halfPalmLength);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool SkeletonModel::getLeftHandPosition(glm::vec3& position) const {
|
bool SkeletonModel::getLeftHandPosition(glm::vec3& position) const {
|
||||||
return getJointPositionInWorldFrame(getLeftHandJointIndex(), position);
|
return getJointPositionInWorldFrame(getLeftHandJointIndex(), position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ public:
|
||||||
/// Returns the index of the right hand joint, or -1 if not found.
|
/// Returns the index of the right hand joint, or -1 if not found.
|
||||||
int getRightHandJointIndex() const { return isActive() ? _geometry->getFBXGeometry().rightHandJointIndex : -1; }
|
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
|
/// Retrieve the position of the left hand
|
||||||
/// \return true whether or not the position was found
|
/// \return true whether or not the position was found
|
||||||
bool getLeftHandPosition(glm::vec3& position) const;
|
bool getLeftHandPosition(glm::vec3& position) const;
|
||||||
|
|
Loading…
Reference in a new issue