mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-24 00:43:51 +02:00
A laser for each hand
This commit is contained in:
parent
bf722f084e
commit
f9ee21525d
2 changed files with 123 additions and 5 deletions
|
@ -410,6 +410,7 @@ void HmdDisplayPlugin::updateFrameData() {
|
||||||
vec3 castDirection = glm::quat_cast(model) * laserDirection;
|
vec3 castDirection = glm::quat_cast(model) * laserDirection;
|
||||||
|
|
||||||
// this offset needs to match GRAB_POINT_SPHERE_OFFSET in scripts/system/libraries/controllers.js:19
|
// this offset needs to match GRAB_POINT_SPHERE_OFFSET in scripts/system/libraries/controllers.js:19
|
||||||
|
// and in vr-edit.js
|
||||||
static const vec3 GRAB_POINT_SPHERE_OFFSET(0.04f, 0.13f, 0.039f); // x = upward, y = forward, z = lateral
|
static const vec3 GRAB_POINT_SPHERE_OFFSET(0.04f, 0.13f, 0.039f); // x = upward, y = forward, z = lateral
|
||||||
|
|
||||||
// swizzle grab point so that (x = upward, y = lateral, z = forward)
|
// swizzle grab point so that (x = upward, y = lateral, z = forward)
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
button,
|
button,
|
||||||
isAppActive = false,
|
isAppActive = false,
|
||||||
|
|
||||||
VR_EDIT_SETTING = "io.highfidelity.isVREditing"; // Note: This constant is duplicated in utils.js.
|
VR_EDIT_SETTING = "io.highfidelity.isVREditing", // Note: This constant is duplicated in utils.js.
|
||||||
|
|
||||||
hands = [],
|
hands = [],
|
||||||
LEFT_HAND = 0,
|
LEFT_HAND = 0,
|
||||||
|
@ -28,7 +28,115 @@
|
||||||
UPDATE_LOOP_TIMEOUT = 16,
|
UPDATE_LOOP_TIMEOUT = 16,
|
||||||
updateTimer = null,
|
updateTimer = null,
|
||||||
|
|
||||||
Hand;
|
Hand,
|
||||||
|
Laser,
|
||||||
|
|
||||||
|
AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
|
||||||
|
|
||||||
|
Laser = function (side) {
|
||||||
|
// May intersect with entities or bounding box of other hand's selection.
|
||||||
|
|
||||||
|
var hand,
|
||||||
|
laserLine = null,
|
||||||
|
laserSphere = null,
|
||||||
|
|
||||||
|
searchDistance = 0.0,
|
||||||
|
|
||||||
|
SEARCH_SPHERE_SIZE = 0.013, // Per handControllerGrab.js multiplied by 1.2 per handControllerGrab.js.
|
||||||
|
SEARCH_SPHERE_FOLLOW_RATE = 0.5, // Per handControllerGrab.js.
|
||||||
|
COLORS_GRAB_SEARCHING_HALF_SQUEEZE = { red: 10, green: 10, blue: 255 }, // Per handControllgerGrab.js.
|
||||||
|
COLORS_GRAB_SEARCHING_FULL_SQUEEZE = { red: 250, green: 10, blue: 10 }; // Per handControllgerGrab.js.
|
||||||
|
|
||||||
|
hand = side;
|
||||||
|
laserLine = Overlays.addOverlay("line3d", {
|
||||||
|
lineWidth: 5,
|
||||||
|
alpha: 1.0,
|
||||||
|
glow: 1.0,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
drawInFront: true,
|
||||||
|
parentID: AVATAR_SELF_ID,
|
||||||
|
parentJointIndex: MyAvatar.getJointIndex(hand === LEFT_HAND
|
||||||
|
? "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"
|
||||||
|
: "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"),
|
||||||
|
visible: false
|
||||||
|
});
|
||||||
|
laserSphere = Overlays.addOverlay("circle3d", {
|
||||||
|
innerAlpha: 1.0,
|
||||||
|
outerAlpha: 0.0,
|
||||||
|
solid: true,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
drawInFront: true,
|
||||||
|
visible: false
|
||||||
|
});
|
||||||
|
|
||||||
|
function colorPow(color, power) {
|
||||||
|
return {
|
||||||
|
red: Math.pow(color.red / 255, power) * 255,
|
||||||
|
green: Math.pow(color.green / 255, power) * 255,
|
||||||
|
blue: Math.pow(color.blue / 255, power) * 255
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLine(start, end, color) {
|
||||||
|
Overlays.editOverlay(laserLine, {
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
color: color,
|
||||||
|
visible: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSphere(location, size, color) {
|
||||||
|
var rotation,
|
||||||
|
brightColor;
|
||||||
|
|
||||||
|
rotation = Quat.lookAt(location, Camera.getPosition(), Vec3.UP);
|
||||||
|
brightColor = colorPow(color, 0.06);
|
||||||
|
|
||||||
|
Overlays.editOverlay(laserSphere, {
|
||||||
|
position: location,
|
||||||
|
rotation: rotation,
|
||||||
|
innerColor: brightColor,
|
||||||
|
outerColor: color,
|
||||||
|
outerRadius: size,
|
||||||
|
visible: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(origin, direction, distance, isClicked) {
|
||||||
|
var searchTarget,
|
||||||
|
sphereSize,
|
||||||
|
color;
|
||||||
|
|
||||||
|
searchDistance = SEARCH_SPHERE_FOLLOW_RATE * searchDistance + (1.0 - SEARCH_SPHERE_FOLLOW_RATE) * distance;
|
||||||
|
searchTarget = Vec3.sum(origin, Vec3.multiply(searchDistance, direction));
|
||||||
|
sphereSize = SEARCH_SPHERE_SIZE * searchDistance;
|
||||||
|
color = isClicked ? COLORS_GRAB_SEARCHING_FULL_SQUEEZE : COLORS_GRAB_SEARCHING_HALF_SQUEEZE;
|
||||||
|
|
||||||
|
updateLine(origin, searchTarget, color);
|
||||||
|
updateSphere(searchTarget, sphereSize, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
Overlays.editOverlay(laserLine, { visible: false });
|
||||||
|
Overlays.editOverlay(laserSphere, { visible: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy() {
|
||||||
|
Overlays.deleteOverlay(laserLine);
|
||||||
|
Overlays.deleteOverlay(laserSphere);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this instanceof Laser) {
|
||||||
|
return new Laser();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
update: update,
|
||||||
|
clear: clear,
|
||||||
|
destroy: destroy
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
Hand = function (side) {
|
Hand = function (side) {
|
||||||
var hand,
|
var hand,
|
||||||
|
@ -46,7 +154,9 @@
|
||||||
NO_EXCLUDE_IDS = [],
|
NO_EXCLUDE_IDS = [],
|
||||||
VISIBLE_ONLY = true,
|
VISIBLE_ONLY = true,
|
||||||
|
|
||||||
isLaserOn = false;
|
isLaserOn = false,
|
||||||
|
|
||||||
|
laser;
|
||||||
|
|
||||||
hand = side;
|
hand = side;
|
||||||
if (hand === LEFT_HAND) {
|
if (hand === LEFT_HAND) {
|
||||||
|
@ -60,6 +170,8 @@
|
||||||
controllerTriggerClicked = Controller.Standard.RTClick;
|
controllerTriggerClicked = Controller.Standard.RTClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
laser = new Laser(hand);
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
var wasLaserOn,
|
var wasLaserOn,
|
||||||
handPose,
|
handPose,
|
||||||
|
@ -75,7 +187,7 @@
|
||||||
isLaserOn = Controller.getValue(controllerTrigger) > (isLaserOn ? TRIGGER_OFF_VALUE : TRIGGER_ON_VALUE);
|
isLaserOn = Controller.getValue(controllerTrigger) > (isLaserOn ? TRIGGER_OFF_VALUE : TRIGGER_ON_VALUE);
|
||||||
if (!isLaserOn) {
|
if (!isLaserOn) {
|
||||||
if (wasLaserOn) {
|
if (wasLaserOn) {
|
||||||
// Clear laser
|
laser.clear();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +197,7 @@
|
||||||
if (!handPose.valid) {
|
if (!handPose.valid) {
|
||||||
isLaserOn = false;
|
isLaserOn = false;
|
||||||
if (wasLaserOn) {
|
if (wasLaserOn) {
|
||||||
// Clear laser
|
laser.clear();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -104,9 +216,14 @@
|
||||||
distance = intersection.intersects ? intersection.distance : PICK_MAX_DISTANCE;
|
distance = intersection.intersects ? intersection.distance : PICK_MAX_DISTANCE;
|
||||||
|
|
||||||
// Update laser.
|
// Update laser.
|
||||||
|
laser.update(pickRay.origin, pickRay.direction, distance, Controller.getValue(controllerTriggerClicked));
|
||||||
}
|
}
|
||||||
|
|
||||||
function destroy() {
|
function destroy() {
|
||||||
|
if (laser) {
|
||||||
|
laser.destroy();
|
||||||
|
laser = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this instanceof Hand) {
|
if (!this instanceof Hand) {
|
||||||
|
|
Loading…
Reference in a new issue