102 lines
4.1 KiB
JavaScript
102 lines
4.1 KiB
JavaScript
// handControllerGrab.js
|
|
//
|
|
// Originally created by Seth Alves on 2016-9-7
|
|
// Modified to Module by Thijs Wenker on 2018-4-23
|
|
// Copyright 2016 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
|
|
/* global module */
|
|
|
|
var GRAB_COMMUNICATIONS_SETTING = "io.highfidelity.isFarGrabbing";
|
|
var setGrabCommunications = function setFarGrabCommunications(on) {
|
|
Settings.setValue(GRAB_COMMUNICATIONS_SETTING, on ? "on" : "");
|
|
};
|
|
|
|
var getGrabCommunications = function getFarGrabCommunications() {
|
|
return !!Settings.getValue(GRAB_COMMUNICATIONS_SETTING, "");
|
|
};
|
|
|
|
// this offset needs to match the one in libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp:378
|
|
// x = upward, y = forward, z = lateral
|
|
var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 };
|
|
|
|
var getGrabPointSphereOffset = function(handController, ignoreSensorToWorldScale) {
|
|
var offset = GRAB_POINT_SPHERE_OFFSET;
|
|
if (handController === Controller.Standard.LeftHand) {
|
|
offset = {
|
|
x: -GRAB_POINT_SPHERE_OFFSET.x,
|
|
y: GRAB_POINT_SPHERE_OFFSET.y,
|
|
z: GRAB_POINT_SPHERE_OFFSET.z
|
|
};
|
|
}
|
|
if (ignoreSensorToWorldScale) {
|
|
return offset;
|
|
} else {
|
|
return Vec3.multiply(MyAvatar.sensorToWorldScale, offset);
|
|
}
|
|
};
|
|
|
|
// controllerWorldLocation is where the controller would be, in-world, with an added offset
|
|
var getControllerWorldLocation = function(handController, shouldAddOffset) {
|
|
var orientation;
|
|
var position;
|
|
var pose = Controller.getPoseValue(handController);
|
|
var valid = pose.valid;
|
|
var controllerJointIndex;
|
|
if (pose.valid) {
|
|
if (handController === Controller.Standard.RightHand) {
|
|
controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND");
|
|
} else {
|
|
controllerJointIndex = MyAvatar.getJointIndex("_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
|
|
}
|
|
orientation = Quat.multiply(MyAvatar.orientation,
|
|
MyAvatar.getAbsoluteJointRotationInObjectFrame(controllerJointIndex));
|
|
position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation,
|
|
MyAvatar.getAbsoluteJointTranslationInObjectFrame(controllerJointIndex)));
|
|
|
|
// add to the real position so the grab-point is out in front of the hand, a bit
|
|
if (shouldAddOffset) {
|
|
var offset = getGrabPointSphereOffset(handController);
|
|
position = Vec3.sum(position, Vec3.multiplyQbyV(orientation, offset));
|
|
}
|
|
|
|
} else if (!HMD.isHandControllerAvailable()) {
|
|
// NOTE: keep this offset in sync with scripts/system/controllers/handControllerPointer.js:493
|
|
var VERTICAL_HEAD_LASER_OFFSET = 0.1 * MyAvatar.sensorToWorldScale;
|
|
position = Vec3.sum(Camera.position,
|
|
Vec3.multiplyQbyV(Camera.orientation, {x: 0, y: VERTICAL_HEAD_LASER_OFFSET, z: 0}));
|
|
orientation = Quat.multiply(Camera.orientation, Quat.angleAxis(-90, { x: 1, y: 0, z: 0 }));
|
|
valid = true;
|
|
}
|
|
|
|
return {
|
|
position: position,
|
|
translation: position,
|
|
orientation: orientation,
|
|
rotation: orientation,
|
|
valid: valid
|
|
};
|
|
};
|
|
|
|
var controllerComputePickRay = function(hand) {
|
|
var controllerPose = getControllerWorldLocation(hand, true);
|
|
if (controllerPose.valid) {
|
|
var controllerPosition = controllerPose.translation;
|
|
// This gets point direction right, but if you want general quaternion it would be more complicated:
|
|
var controllerDirection = Quat.getUp(controllerPose.rotation);
|
|
return {
|
|
origin: controllerPosition,
|
|
direction: controllerDirection
|
|
};
|
|
}
|
|
return null;
|
|
};
|
|
|
|
module.exports = {
|
|
controllerComputePickRay: controllerComputePickRay,
|
|
setGrabCommunications: setGrabCommunications,
|
|
getGrabCommunications: getGrabCommunications,
|
|
getGrabPointSphereOffset: getGrabPointSphereOffset,
|
|
getControllerWorldLocation: getControllerWorldLocation
|
|
};
|