Karol SuprynowiczFix Uuid.NULL behaviord38ebbd2 years agoHistory
226 lines · 9.8 KB · JavaScript
RawDownload
"no use strict"; //  stylusInput.js////  Copyright 2017-2020 High Fidelity, Inc.//  Copyright 2023 Overte e.V.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html//  SPDX-License-Identifier: Apache-2.0// /* global Script, MyAvatar, Controller, Uuid, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule,   makeRunningValues, Vec3, makeDispatcherModuleParameters, Overlays, HMD, Settings, getEnabledModuleByName, Pointers,   Picks, PickType, Keyboard*/ Script.include("/~/system/libraries/controllerDispatcherUtils.js");Script.include("/~/system/libraries/controllers.js"); (function() {    function isNearStylusTarget(stylusTargets, maxNormalDistance) {        var stylusTargetIDs = [];        for (var index = 0; index < stylusTargets.length; index++) {            var stylusTarget = stylusTargets[index];            if (stylusTarget.distance <= maxNormalDistance && !(HMD.tabletID && stylusTarget.id === HMD.tabletID)) {                stylusTargetIDs.push(stylusTarget.id);            }        }        return stylusTargetIDs;    }     function getOverlayDistance(controllerPosition, overlayID) {        var position = Entities.getEntityProperties(overlayID, ["position"]).position;        return {            id: overlayID,            distance: Vec3.distance(position, controllerPosition)        };    }     function StylusInput(hand) {        this.hand = hand;         this.parameters = makeDispatcherModuleParameters(            100,            this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],            [],            100);         //V8TODO        this.pointer = Pointers.createStylusPointer({            hand: this.hand,            filter: Picks.PICK_OVERLAYS,            hover: true,            enabled: true        });         this.disable = false;         this.otherModuleNeedsToRun = function(controllerData) {            var grabEntityModuleName = this.hand === RIGHT_HAND ? "RightNearGrabEntity" : "LeftNearGrabEntity";            var grabEntityModule = getEnabledModuleByName(grabEntityModuleName);            var grabEntityModuleReady = grabEntityModule ? grabEntityModule.isReady(controllerData) : makeRunningValues(false, [], []);             var farGrabModuleName = this.hand === RIGHT_HAND ? "RightFarGrabEntity" : "LeftFarGrabEntity";            var farGrabModule = getEnabledModuleByName(farGrabModuleName);            var farGrabModuleReady = farGrabModule ? farGrabModule.isReady(controllerData) : makeRunningValues(false, [], []);             var nearTabletHighlightModuleName =                this.hand === RIGHT_HAND ? "RightNearTabletHighlight" : "LeftNearTabletHighlight";            var nearTabletHighlightModule = getEnabledModuleByName(nearTabletHighlightModuleName);            var nearTabletHighlightModuleReady = nearTabletHighlightModule ?                nearTabletHighlightModule.isReady(controllerData) : makeRunningValues(false, [], []);             return farGrabModuleReady.active || grabEntityModuleReady.active;        };         this.overlayLaserActive = function(controllerData) {            var rightOverlayLaserModule = getEnabledModuleByName("RightWebSurfaceLaserInput");            var leftOverlayLaserModule = getEnabledModuleByName("LeftWebSurfaceLaserInput");            var rightModuleRunning = rightOverlayLaserModule ? rightOverlayLaserModule.isReady(controllerData).active : false;            var leftModuleRunning = leftOverlayLaserModule ? leftOverlayLaserModule.isReady(controllerData).active : false;            return leftModuleRunning || rightModuleRunning;        };         this.processStylus = function(controllerData) {            if (this.overlayLaserActive(controllerData) || this.otherModuleNeedsToRun(controllerData)) {                Pointers.setRenderState(this.pointer, "disabled");                return false;            }             var sensorScaleFactor = MyAvatar.sensorToWorldScale;             // build list of stylus targets, near the stylusTip            var stylusTargets = [];            var candidateOverlays = controllerData.nearbyOverlayIDs;            var controllerPosition = controllerData.controllerLocations[this.hand].position;            var i, stylusTarget;             for (i = 0; i < candidateOverlays.length; i++) {                if (!(HMD.tabletID && candidateOverlays[i] === HMD.tabletID) &&                    Entities.getEntityProperties(candidateOverlays[i], ["visible"]).visible) {                    stylusTarget = getOverlayDistance(controllerPosition, candidateOverlays[i]);                    if (stylusTarget) {                        stylusTargets.push(stylusTarget);                    }                }            }             // add the tabletScreen, if it is valid            if (HMD.tabletScreenID && HMD.tabletScreenID !== Uuid.NONE &&                Entities.getEntityProperties(HMD.tabletScreenID, ["visible"]).visible) {                stylusTarget = getOverlayDistance(controllerPosition, HMD.tabletScreenID);                if (stylusTarget) {                    stylusTargets.push(stylusTarget);                }            }             // add the tablet home button.            if (HMD.homeButtonID && HMD.homeButtonID !== Uuid.NONE &&                Entities.getEntityProperties(HMD.homeButtonID, ["visible"]).visible) {                stylusTarget = getOverlayDistance(controllerPosition, HMD.homeButtonID);                if (stylusTarget) {                    stylusTargets.push(stylusTarget);                }            }             // Add the mini tablet.            if (HMD.miniTabletScreenID && Entities.getEntityProperties(HMD.miniTabletScreenID, ["visible"]).visible &&                this.hand != HMD.miniTabletHand) {                stylusTarget = getOverlayDistance(controllerPosition, HMD.miniTabletScreenID);                if (stylusTarget) {                    stylusTargets.push(stylusTarget);                }            }             var WEB_DISPLAY_STYLUS_DISTANCE = (Keyboard.raised && Keyboard.preferMalletsOverLasers) ? 0.2 : 0.5;            var nearStylusTarget = isNearStylusTarget(stylusTargets, WEB_DISPLAY_STYLUS_DISTANCE * sensorScaleFactor);             if (nearStylusTarget.length !== 0) {                if (!this.disable) {                    Pointers.setRenderState(this.pointer,"events on");                    Pointers.setIncludeItems(this.pointer, nearStylusTarget);                } else {                    Pointers.setRenderState(this.pointer,"events off");                }                return true;            } else {                Pointers.setRenderState(this.pointer, "disabled");                Pointers.setIncludeItems(this.pointer, []);                return false;            }        };         this.isReady = function (controllerData) {            var PREFER_STYLUS_OVER_LASER = "preferStylusOverLaser";            var isUsingStylus = Settings.getValue(PREFER_STYLUS_OVER_LASER, false);             if (isUsingStylus && this.processStylus(controllerData)) {                Pointers.enablePointer(this.pointer);                this.hand === RIGHT_HAND ? Keyboard.disableRightMallet() : Keyboard.disableLeftMallet();                return makeRunningValues(true, [], []);            } else {                Pointers.disablePointer(this.pointer);                if (Keyboard.raised && Keyboard.preferMalletsOverLasers) {                    this.hand === RIGHT_HAND ? Keyboard.enableRightMallet() : Keyboard.enableLeftMallet();                }                return makeRunningValues(false, [], []);            }        };         this.run = function (controllerData, deltaTime) {            return this.isReady(controllerData);        };         this.cleanup = function () {            Pointers.removePointer(this.pointer);        };    }     function mouseHoverEnter(overlayID, event) {        if (event.id === leftTabletStylusInput.pointer && !rightTabletStylusInput.disable && !leftTabletStylusInput.disable) {            rightTabletStylusInput.disable = true;        } else if (event.id === rightTabletStylusInput.pointer && !leftTabletStylusInput.disable && !rightTabletStylusInput.disable) {            leftTabletStylusInput.disable = true;        }    }     function mouseHoverLeave(overlayID, event) {        if (event.id === leftTabletStylusInput.pointer) {            rightTabletStylusInput.disable = false;        } else if (event.id === rightTabletStylusInput.pointer) {            leftTabletStylusInput.disable = false;        }    }     var HAPTIC_STYLUS_STRENGTH = 1.0;    var HAPTIC_STYLUS_DURATION = 20.0;    function mousePress(overlayID, event) {        if (HMD.active) {            if (event.id === leftTabletStylusInput.pointer && event.button === "Primary") {                Controller.triggerHapticPulse(HAPTIC_STYLUS_STRENGTH, HAPTIC_STYLUS_DURATION, LEFT_HAND);            } else if (event.id === rightTabletStylusInput.pointer && event.button === "Primary") {                Controller.triggerHapticPulse(HAPTIC_STYLUS_STRENGTH, HAPTIC_STYLUS_DURATION, RIGHT_HAND);            }        }    }     var leftTabletStylusInput = new StylusInput(LEFT_HAND);    var rightTabletStylusInput = new StylusInput(RIGHT_HAND);     enableDispatcherModule("LeftTabletStylusInput", leftTabletStylusInput);    enableDispatcherModule("RightTabletStylusInput", rightTabletStylusInput);     Overlays.hoverEnterOverlay.connect(mouseHoverEnter);    Overlays.hoverLeaveOverlay.connect(mouseHoverLeave);    Overlays.mousePressOnOverlay.connect(mousePress);     this.cleanup = function () {        leftTabletStylusInput.cleanup();        rightTabletStylusInput.cleanup();        disableDispatcherModule("LeftTabletStylusInput");        disableDispatcherModule("RightTabletStylusInput");    };    Script.scriptEnding.connect(this.cleanup);}());