229 lines · 9.5 KB · JavaScript
RawDownload
"use strict"; //  touchEventUtils.js////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,   enableDispatcherModule, disableDispatcherModule, makeRunningValues,   Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, controllerDispatcher.ZERO_VEC,   HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset*/ var controllerDispatcher = Script.require("/~/system/libraries/controllerDispatcherUtils.js");function touchTargetHasKeyboardFocus(touchTarget) {    if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {        return Entities.keyboardFocusEntity === touchTarget.entityID;    } else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {        return Overlays.keyboardFocusOverlay === touchTarget.overlayID;    }} function setKeyboardFocusOnTouchTarget(touchTarget) {    if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE &&        Entities.wantsHandControllerPointerEvents(touchTarget.entityID)) {        Overlays.keyboardFocusOverlay = Uuid.NONE;        Entities.keyboardFocusEntity = touchTarget.entityID;    } else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {        Overlays.keyboardFocusOverlay = touchTarget.overlayID;        Entities.keyboardFocusEntity = Uuid.NONE;    }} function sendHoverEnterEventToTouchTarget(hand, touchTarget) {    var pointerEvent = {        type: "Move",        id: hand + 1, // 0 is reserved for hardware mouse        pos2D: touchTarget.position2D,        pos3D: touchTarget.position,        normal: touchTarget.normal,        direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),        button: "None"    };     if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {        Entities.sendHoverEnterEntity(touchTarget.entityID, pointerEvent);    } else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {        Overlays.sendHoverEnterOverlay(touchTarget.overlayID, pointerEvent);    }} function sendHoverOverEventToTouchTarget(hand, touchTarget) {    var pointerEvent = {        type: "Move",        id: hand + 1, // 0 is reserved for hardware mouse        pos2D: touchTarget.position2D,        pos3D: touchTarget.position,        normal: touchTarget.normal,        direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),        button: "None"    };     if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {        Entities.sendMouseMoveOnEntity(touchTarget.entityID, pointerEvent);        Entities.sendHoverOverEntity(touchTarget.entityID, pointerEvent);    } else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {        Overlays.sendMouseMoveOnOverlay(touchTarget.overlayID, pointerEvent);        Overlays.sendHoverOverOverlay(touchTarget.overlayID, pointerEvent);    }} function sendTouchStartEventToTouchTarget(hand, touchTarget) {    var pointerEvent = {        type: "Press",        id: hand + 1, // 0 is reserved for hardware mouse        pos2D: touchTarget.position2D,        pos3D: touchTarget.position,        normal: touchTarget.normal,        direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),        button: "Primary",        isPrimaryHeld: true    };     if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {        Entities.sendMousePressOnEntity(touchTarget.entityID, pointerEvent);        Entities.sendClickDownOnEntity(touchTarget.entityID, pointerEvent);    } else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {        Overlays.sendMousePressOnOverlay(touchTarget.overlayID, pointerEvent);    }} function sendTouchEndEventToTouchTarget(hand, touchTarget) {    var pointerEvent = {        type: "Release",        id: hand + 1, // 0 is reserved for hardware mouse        pos2D: touchTarget.position2D,        pos3D: touchTarget.position,        normal: touchTarget.normal,        direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),        button: "Primary"    };     if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {        Entities.sendMouseReleaseOnEntity(touchTarget.entityID, pointerEvent);        Entities.sendClickReleaseOnEntity(touchTarget.entityID, pointerEvent);        Entities.sendHoverLeaveEntity(touchTarget.entityID, pointerEvent);    } else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {        Overlays.sendMouseReleaseOnOverlay(touchTarget.overlayID, pointerEvent);    }} function sendTouchMoveEventToTouchTarget(hand, touchTarget) {    var pointerEvent = {        type: "Move",        id: hand + 1, // 0 is reserved for hardware mouse        pos2D: touchTarget.position2D,        pos3D: touchTarget.position,        normal: touchTarget.normal,        direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),        button: "Primary",        isPrimaryHeld: true    };     if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {        Entities.sendMouseMoveOnEntity(touchTarget.entityID, pointerEvent);        Entities.sendHoldingClickOnEntity(touchTarget.entityID, pointerEvent);    } else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {        Overlays.sendMouseMoveOnOverlay(touchTarget.overlayID, pointerEvent);    }} // will return undefined if overlayID does not exist.function calculateTouchTargetFromOverlay(touchTip, overlayID) {    var overlayPosition = Entities.getEntityProperties(overlayID, ["position"]).position;    if (overlayPosition === undefined) {        return;    }     // project touchTip onto overlay plane.    var overlayRotation = Entities.getEntityProperties(overlayID, ["rotation"]).rotation;    if (overlayRotation === undefined) {        return;    }    var normal = Vec3.multiplyQbyV(overlayRotation, {x: 0, y: 0, z: 1});    var distance = Vec3.dot(Vec3.subtract(touchTip.position, overlayPosition), normal);    var position = Vec3.subtract(touchTip.position, Vec3.multiply(normal, distance));     // calclulate normalized position    var invRot = Quat.inverse(overlayRotation);    var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, overlayPosition));     // V8TODO: check if this is correct for entities    var dimensions = Entities.getEntityProperties(overlayID, ["dimensions"]).dimensions;    if (dimensions === undefined) {        return;    }    dimensions.z = 0.01; // we are projecting onto the XY plane of the overlay, so ignore the z dimension    var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z };    var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT);     // 2D position on overlay plane in meters, relative to the bounding box upper-left hand corner.    var position2D = {        x: normalizedPosition.x * dimensions.x,        y: (1 - normalizedPosition.y) * dimensions.y // flip y-axis    };     return {        entityID: null,        overlayID: overlayID,        distance: distance,        position: position,        position2D: position2D,        normal: normal,        normalizedPosition: normalizedPosition,        dimensions: dimensions,        valid: true    };} // will return undefined if entity does not exist.function calculateTouchTargetFromEntity(touchTip, props) {    if (props.rotation === undefined) {        // if rotation is missing from props object, then this entity has probably been deleted.        return;    }     // project touch tip onto entity plane.    var normal = Vec3.multiplyQbyV(props.rotation, {x: 0, y: 0, z: 1});    Vec3.multiplyQbyV(props.rotation, {x: 0, y: 1, z: 0});    var distance = Vec3.dot(Vec3.subtract(touchTip.position, props.position), normal);    var position = Vec3.subtract(touchTip.position, Vec3.multiply(normal, distance));     // generate normalized coordinates    var invRot = Quat.inverse(props.rotation);    var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, props.position));    var invDimensions = { x: 1 / props.dimensions.x, y: 1 / props.dimensions.y, z: 1 / props.dimensions.z };    var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint);     // 2D position on entity plane in meters, relative to the bounding box upper-left hand corner.    var position2D = {        x: normalizedPosition.x * props.dimensions.x,        y: (1 - normalizedPosition.y) * props.dimensions.y // flip y-axis    };     return {        entityID: props.id,        entityProps: props,        overlayID: null,        distance: distance,        position: position,        position2D: position2D,        normal: normal,        normalizedPosition: normalizedPosition,        dimensions: props.dimensions,        valid: true    };} module.exports = {    calculateTouchTargetFromEntity: calculateTouchTargetFromEntity,    calculateTouchTargetFromOverlay: calculateTouchTargetFromOverlay,    touchTargetHasKeyboardFocus: touchTargetHasKeyboardFocus,    setKeyboardFocusOnTouchTarget: setKeyboardFocusOnTouchTarget,    sendHoverEnterEventToTouchTarget: sendHoverEnterEventToTouchTarget,    sendHoverOverEventToTouchTarget: sendHoverOverEventToTouchTarget,    sendTouchStartEventToTouchTarget: sendTouchStartEventToTouchTarget,    sendTouchEndEventToTouchTarget: sendTouchEndEventToTouchTarget,    sendTouchMoveEventToTouchTarget: sendTouchMoveEventToTouchTarget,};