overte/scripts/vr-edit/vr-edit.js
2017-07-05 12:49:36 +12:00

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);
}());