mirror of
https://github.com/overte-org/overte.git
synced 2025-05-06 16:09:49 +02:00
211 lines
5.9 KiB
JavaScript
211 lines
5.9 KiB
JavaScript
"use strict";
|
|
|
|
//
|
|
// vr-edit.js
|
|
//
|
|
// Created by David Rowe on 27 Jun 2017.
|
|
// Copyright 2017 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
|
|
//
|
|
|
|
(function () {
|
|
|
|
var APP_NAME = "VR EDIT", // TODO: App name.
|
|
APP_ICON_INACTIVE = "icons/tablet-icons/edit-i.svg", // TODO: App icons.
|
|
APP_ICON_ACTIVE = "icons/tablet-icons/edit-a.svg",
|
|
tablet,
|
|
button,
|
|
isAppActive = false,
|
|
|
|
VR_EDIT_SETTING = "io.highfidelity.isVREditing"; // Note: This constant is duplicated in utils.js.
|
|
|
|
hands = [],
|
|
LEFT_HAND = 0,
|
|
RIGHT_HAND = 1,
|
|
|
|
UPDATE_LOOP_TIMEOUT = 16,
|
|
updateTimer = null,
|
|
|
|
Hand;
|
|
|
|
Hand = function (side) {
|
|
var hand,
|
|
handController,
|
|
controllerTrigger,
|
|
controllerTriggerClicked,
|
|
|
|
TRIGGER_ON_VALUE = 0.15, // Per handControllerGrab.js.
|
|
TRIGGER_OFF_VALUE = 0.1, // Per handControllerGrab.js.
|
|
GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }, // Per HmdDisplayPlugin.cpp and controllers.js.
|
|
|
|
PICK_MAX_DISTANCE = 500, // Per handControllerGrab.js.
|
|
PRECISION_PICKING = true,
|
|
NO_INCLUDE_IDS = [],
|
|
NO_EXCLUDE_IDS = [],
|
|
VISIBLE_ONLY = true,
|
|
|
|
isLaserOn = false;
|
|
|
|
hand = side;
|
|
if (hand === LEFT_HAND) {
|
|
handController = Controller.Standard.LeftHand;
|
|
controllerTrigger = Controller.Standard.LT;
|
|
controllerTriggerClicked = Controller.Standard.LTClick;
|
|
GRAB_POINT_SPHERE_OFFSET.x = -GRAB_POINT_SPHERE_OFFSET.x;
|
|
} else {
|
|
handController = Controller.Standard.RightHand;
|
|
controllerTrigger = Controller.Standard.RT;
|
|
controllerTriggerClicked = Controller.Standard.RTClick;
|
|
}
|
|
|
|
function update() {
|
|
var wasLaserOn,
|
|
handPose,
|
|
handPosition,
|
|
handOrientation,
|
|
deltaOrigin,
|
|
pickRay,
|
|
intersection,
|
|
distance;
|
|
|
|
// Controller trigger.
|
|
wasLaserOn = isLaserOn;
|
|
isLaserOn = Controller.getValue(controllerTrigger) > (isLaserOn ? TRIGGER_OFF_VALUE : TRIGGER_ON_VALUE);
|
|
if (!isLaserOn) {
|
|
if (wasLaserOn) {
|
|
// Clear laser
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Hand position and orientation.
|
|
handPose = Controller.getPoseValue(handController);
|
|
if (!handPose.valid) {
|
|
isLaserOn = false;
|
|
if (wasLaserOn) {
|
|
// Clear laser
|
|
}
|
|
return;
|
|
}
|
|
handPosition = Vec3.sum(Vec3.multiplyQbyV(MyAvatar.orientation, handPose.translation), MyAvatar.position);
|
|
handOrientation = Quat.multiply(MyAvatar.orientation, handPose.rotation);
|
|
|
|
// Entity intersection, if any.
|
|
deltaOrigin = Vec3.multiplyQbyV(handOrientation, GRAB_POINT_SPHERE_OFFSET);
|
|
pickRay = {
|
|
origin: Vec3.sum(handPosition, deltaOrigin), // Add a bit to ...
|
|
direction: Quat.getUp(handOrientation),
|
|
length: PICK_MAX_DISTANCE
|
|
};
|
|
intersection = Entities.findRayIntersection(pickRay, PRECISION_PICKING, NO_INCLUDE_IDS, NO_EXCLUDE_IDS,
|
|
VISIBLE_ONLY);
|
|
distance = intersection.intersects ? intersection.distance : PICK_MAX_DISTANCE;
|
|
|
|
// Update laser.
|
|
}
|
|
|
|
function destroy() {
|
|
}
|
|
|
|
if (!this instanceof Hand) {
|
|
return new Hand();
|
|
}
|
|
|
|
return {
|
|
update: update,
|
|
destroy: destroy
|
|
};
|
|
};
|
|
|
|
|
|
function update() {
|
|
// Main update loop.
|
|
updateTimer = null;
|
|
|
|
hands[LEFT_HAND].update();
|
|
hands[RIGHT_HAND].update();
|
|
|
|
updateTimer = Script.setTimeout(update, UPDATE_LOOP_TIMEOUT);
|
|
}
|
|
|
|
function updateHandControllerGrab() {
|
|
// Communicate status to handControllerGrab.js.
|
|
Settings.setValue(VR_EDIT_SETTING, isAppActive);
|
|
}
|
|
|
|
function onButtonClicked() {
|
|
isAppActive = !isAppActive;
|
|
updateHandControllerGrab();
|
|
button.editProperties({ isActive: isAppActive });
|
|
|
|
if (isAppActive) {
|
|
update();
|
|
} else {
|
|
Script.clearTimeout(updateTimer);
|
|
updateTimer = null;
|
|
}
|
|
}
|
|
|
|
function setUp() {
|
|
updateHandControllerGrab();
|
|
|
|
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
if (!tablet) {
|
|
return;
|
|
}
|
|
|
|
// Tablet/toolbar button.
|
|
button = tablet.addButton({
|
|
icon: APP_ICON_INACTIVE,
|
|
activeIcon: APP_ICON_ACTIVE,
|
|
text: APP_NAME,
|
|
isActive: isAppActive
|
|
});
|
|
if (button) {
|
|
button.clicked.connect(onButtonClicked);
|
|
}
|
|
|
|
// Hands, each with a laser, selection, etc.
|
|
hands[LEFT_HAND] = new Hand(LEFT_HAND);
|
|
hands[RIGHT_HAND] = new Hand(RIGHT_HAND);
|
|
|
|
if (isAppActive) {
|
|
update();
|
|
}
|
|
}
|
|
|
|
function tearDown() {
|
|
if (updateTimer) {
|
|
Script.clearTimeout(updateTimer);
|
|
}
|
|
|
|
isAppActive = false;
|
|
updateHandControllerGrab();
|
|
|
|
if (!tablet) {
|
|
return;
|
|
}
|
|
|
|
if (button) {
|
|
button.clicked.disconnect(onButtonClicked);
|
|
tablet.removeButton(button);
|
|
button = null;
|
|
}
|
|
|
|
if (hands[LEFT_HAND]) {
|
|
hands[LEFT_HAND].destroy();
|
|
hands[LEFT_HAND] = null;
|
|
}
|
|
if (hands[RIGHT_HAND]) {
|
|
hands[RIGHT_HAND].destroy();
|
|
hands[RIGHT_HAND] = null;
|
|
}
|
|
|
|
tablet = null;
|
|
}
|
|
|
|
setUp();
|
|
Script.scriptEnding.connect(tearDown);
|
|
}());
|