mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #9243 from sethalves/tablet-ui-overlay-stylus-rebase
use overlays for tablet-ui, use a stylus rather than lasers
This commit is contained in:
commit
9d964042c9
7 changed files with 288 additions and 155 deletions
|
@ -171,7 +171,7 @@ Item {
|
|||
console.log("Tablet.onCompleted!");
|
||||
var component = Qt.createComponent("TabletButton.qml");
|
||||
var buttons = [];
|
||||
for (var i = 0; i < 5; i++) {
|
||||
for (var i = 0; i < 6; i++) {
|
||||
var button = component.createObject(flowMain);
|
||||
button.inDebugMode = true;
|
||||
buttons.push(button);
|
||||
|
|
|
@ -1592,7 +1592,15 @@ void Application::toggleMenuUnderReticle() const {
|
|||
offscreenUi->toggleMenu(QPoint(reticlePosition.x - X_LEFT_SHIFT, reticlePosition.y));
|
||||
}
|
||||
|
||||
uint64_t lastTabletUIToggle { 0 };
|
||||
const uint64_t toggleTabletUILockout { 500000 };
|
||||
void Application::toggleTabletUI() const {
|
||||
uint64_t now = usecTimestampNow();
|
||||
if (now - lastTabletUIToggle < toggleTabletUILockout) {
|
||||
return;
|
||||
}
|
||||
lastTabletUIToggle = now;
|
||||
|
||||
auto HMD = DependencyManager::get<HMDScriptingInterface>();
|
||||
HMD->toggleShouldShowTablet();
|
||||
}
|
||||
|
|
|
@ -18,16 +18,16 @@
|
|||
#include <QtQuick/QQuickItem>
|
||||
#include <QtQml/QQmlContext>
|
||||
|
||||
#include <AbstractViewStateInterface.h>
|
||||
#include <gpu/Batch.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <GeometryUtil.h>
|
||||
#include <TextureCache.h>
|
||||
#include <PathUtils.h>
|
||||
#include <gpu/Batch.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <AbstractViewStateInterface.h>
|
||||
|
||||
#include <gl/OffscreenQmlSurface.h>
|
||||
#include <PathUtils.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <TabletScriptingInterface.h>
|
||||
#include <TextureCache.h>
|
||||
|
||||
static const float DPI = 30.47f;
|
||||
static const float INCHES_TO_METERS = 1.0f / 39.3701f;
|
||||
|
@ -36,7 +36,7 @@ static const float OPAQUE_ALPHA_THRESHOLD = 0.99f;
|
|||
|
||||
QString const Web3DOverlay::TYPE = "web3d";
|
||||
|
||||
Web3DOverlay::Web3DOverlay() : _dpi(DPI) {
|
||||
Web3DOverlay::Web3DOverlay() : _dpi(DPI) {
|
||||
_touchDevice.setCapabilities(QTouchDevice::Position);
|
||||
_touchDevice.setType(QTouchDevice::TouchScreen);
|
||||
_touchDevice.setName("RenderableWebEntityItemTouchDevice");
|
||||
|
@ -57,6 +57,24 @@ Web3DOverlay::Web3DOverlay(const Web3DOverlay* Web3DOverlay) :
|
|||
|
||||
Web3DOverlay::~Web3DOverlay() {
|
||||
if (_webSurface) {
|
||||
QQuickItem* rootItem = _webSurface->getRootItem();
|
||||
|
||||
// TABLET_UI_HACK: TODO: update this with rootTablet
|
||||
if (rootItem && rootItem->objectName() == "tablet") {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
tabletScriptingInterface->setQmlTablet("com.highfidelity.interface.tablet.system", nullptr);
|
||||
}
|
||||
|
||||
// Fix for crash in QtWebEngineCore when rapidly switching domains
|
||||
// Call stop on the QWebEngineView before destroying OffscreenQMLSurface.
|
||||
if (rootItem) {
|
||||
QObject* obj = rootItem->findChild<QObject*>("webEngineView");
|
||||
if (obj) {
|
||||
// stop loading
|
||||
QMetaObject::invokeMethod(obj, "stop");
|
||||
}
|
||||
}
|
||||
|
||||
_webSurface->pause();
|
||||
_webSurface->disconnect(_connection);
|
||||
|
||||
|
@ -101,6 +119,32 @@ void Web3DOverlay::update(float deltatime) {
|
|||
*/
|
||||
}
|
||||
|
||||
void Web3DOverlay::loadSourceURL() {
|
||||
|
||||
QUrl sourceUrl(_url);
|
||||
if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" ||
|
||||
_url.toLower().endsWith(".htm") || _url.toLower().endsWith(".html")) {
|
||||
|
||||
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
||||
_webSurface->load("Web3DOverlay.qml");
|
||||
_webSurface->resume();
|
||||
_webSurface->getRootItem()->setProperty("url", _url);
|
||||
_webSurface->getRootItem()->setProperty("scriptURL", _scriptURL);
|
||||
_webSurface->getRootContext()->setContextProperty("ApplicationInterface", qApp);
|
||||
|
||||
} else {
|
||||
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath()));
|
||||
_webSurface->load(_url, [&](QQmlContext* context, QObject* obj) {});
|
||||
_webSurface->resume();
|
||||
|
||||
// TABLET_UI_HACK: TODO: update this to use rootTablet.
|
||||
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tablet") {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
tabletScriptingInterface->setQmlTablet("com.highfidelity.interface.tablet.system", _webSurface->getRootItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Web3DOverlay::render(RenderArgs* args) {
|
||||
if (!_visible || !getParentVisible()) {
|
||||
return;
|
||||
|
@ -119,12 +163,9 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
// and the current rendering load)
|
||||
_webSurface->setMaxFps(10);
|
||||
_webSurface->create(currentContext);
|
||||
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
||||
_webSurface->load("Web3DOverlay.qml");
|
||||
_webSurface->resume();
|
||||
_webSurface->getRootItem()->setProperty("url", _url);
|
||||
_webSurface->getRootItem()->setProperty("scriptURL", _scriptURL);
|
||||
_webSurface->getRootContext()->setContextProperty("ApplicationInterface", qApp);
|
||||
|
||||
loadSourceURL();
|
||||
|
||||
_webSurface->resize(QSize(_resolution.x, _resolution.y));
|
||||
currentContext->makeCurrent(currentSurface);
|
||||
|
||||
|
@ -150,7 +191,7 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
point.setPos(windowPoint);
|
||||
QList<QTouchEvent::TouchPoint> touchPoints;
|
||||
touchPoints.push_back(point);
|
||||
QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, Qt::NoModifier, Qt::TouchPointReleased,
|
||||
QTouchEvent* touchEvent = new QTouchEvent(QEvent::TouchEnd, nullptr, Qt::NoModifier, Qt::TouchPointReleased,
|
||||
touchPoints);
|
||||
touchEvent->setWindow(_webSurface->getWindow());
|
||||
touchEvent->setDevice(&_touchDevice);
|
||||
|
@ -167,7 +208,7 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
vec4 color(toGlm(getColor()), getAlpha());
|
||||
|
||||
Transform transform = getTransform();
|
||||
|
||||
|
||||
// FIXME: applyTransformTo causes tablet overlay to detach from tablet entity.
|
||||
// Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true?
|
||||
/*
|
||||
|
@ -237,7 +278,7 @@ void Web3DOverlay::handlePointerEvent(const PointerEvent& event) {
|
|||
|
||||
if (event.getType() == PointerEvent::Move) {
|
||||
// Forward a mouse move event to the Web surface.
|
||||
QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, Qt::NoButton,
|
||||
QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, Qt::NoButton,
|
||||
Qt::NoButton, Qt::NoModifier);
|
||||
QCoreApplication::postEvent(_webSurface->getWindow(), mouseEvent);
|
||||
}
|
||||
|
@ -338,7 +379,7 @@ void Web3DOverlay::setURL(const QString& url) {
|
|||
_url = url;
|
||||
if (_webSurface) {
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this, url] {
|
||||
_webSurface->getRootItem()->setProperty("url", url);
|
||||
loadSourceURL();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
Web3DOverlay(const Web3DOverlay* Web3DOverlay);
|
||||
virtual ~Web3DOverlay();
|
||||
|
||||
void loadSourceURL();
|
||||
virtual void render(RenderArgs* args) override;
|
||||
virtual const render::ShapeKey getShapeKey() override;
|
||||
|
||||
|
@ -46,7 +47,7 @@ public:
|
|||
|
||||
glm::vec2 getSize();
|
||||
|
||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
BoxFace& face, glm::vec3& surfaceNormal) override;
|
||||
|
||||
virtual Web3DOverlay* createClone() const override;
|
||||
|
|
|
@ -366,6 +366,8 @@ void RenderableWebEntityItem::destroyWebSurface() {
|
|||
tabletScriptingInterface->setQmlTablet("com.highfidelity.interface.tablet.system", nullptr);
|
||||
}
|
||||
|
||||
// Fix for crash in QtWebEngineCore when rapidly switching domains
|
||||
// Call stop on the QWebEngineView before destroying OffscreenQMLSurface.
|
||||
if (rootItem) {
|
||||
QObject* obj = rootItem->findChild<QObject*>("webEngineView");
|
||||
if (obj) {
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global setEntityCustomData, getEntityCustomData, flatten, Xform, Script, Quat, Vec3, MyAvatar, Entities, Overlays, Settings,
|
||||
Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset, setGrabCommunications */
|
||||
Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset, setGrabCommunications,
|
||||
Menu */
|
||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
@ -61,6 +62,12 @@ var PICK_WITH_HAND_RAY = true;
|
|||
|
||||
var EQUIP_SPHERE_SCALE_FACTOR = 0.65;
|
||||
|
||||
var WEB_TOUCH_SPHERE_RADIUS = 0.017;
|
||||
var WEB_STYLUS_COLOR = { red: 0, green: 240, blue: 0 };
|
||||
var WEB_STYLUS_TIP_COLOR = { red: 0, green: 0, blue: 240 };
|
||||
var WEB_STYLUS_ALPHA = 1.0;
|
||||
var WEB_DISPLAY_STYLUS_DISTANCE = 1.0;
|
||||
var WEB_TOUCH_DISTANCE = 0.2;
|
||||
|
||||
//
|
||||
// distant manipulation
|
||||
|
@ -747,6 +754,7 @@ function MyController(hand) {
|
|||
this.hand = hand;
|
||||
this.autoUnequipCounter = 0;
|
||||
this.grabPointIntersectsEntity = false;
|
||||
this.stylus = null;
|
||||
|
||||
this.shouldScale = false;
|
||||
|
||||
|
@ -946,6 +954,62 @@ function MyController(hand) {
|
|||
}
|
||||
};
|
||||
|
||||
this.showStylus = function() {
|
||||
if (this.stylus) {
|
||||
return;
|
||||
}
|
||||
if (!MyAvatar.sessionUUID) {
|
||||
return;
|
||||
}
|
||||
print("SHOW");
|
||||
var stylusTipProperties = {
|
||||
localPosition: Vec3.sum({ x: 0, y: WEB_TOUCH_DISTANCE - (WEB_TOUCH_SPHERE_RADIUS / 2.0), z: 0 },
|
||||
getGrabPointSphereOffset(this.handToController())),
|
||||
localRotation: { x: 0, y: 0, z: 0, w: 1 },
|
||||
dimensions: WEB_TOUCH_SPHERE_RADIUS,
|
||||
color: WEB_STYLUS_TIP_COLOR,
|
||||
alpha: WEB_STYLUS_ALPHA,
|
||||
solid: true,
|
||||
visible: true,
|
||||
ignoreRayIntersection: true,
|
||||
drawInFront: false,
|
||||
parentID: MyAvatar.sessionUUID,
|
||||
parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ?
|
||||
"_CONTROLLER_RIGHTHAND" :
|
||||
"_CONTROLLER_LEFTHAND")
|
||||
};
|
||||
this.stylusTip = Overlays.addOverlay("sphere", stylusTipProperties);
|
||||
|
||||
var stylusProperties = {
|
||||
localPosition: Vec3.sum({ x: 0.0, y: WEB_TOUCH_DISTANCE / 2.0, z: 0.0 },
|
||||
getGrabPointSphereOffset(this.handToController())),
|
||||
localRotation: { x: 0, y: 0, z: 0, w: 1 },
|
||||
dimensions: { x: 0.01, y: WEB_TOUCH_DISTANCE - WEB_TOUCH_SPHERE_RADIUS, z: 0.01 },
|
||||
color: WEB_STYLUS_COLOR,
|
||||
alpha: WEB_STYLUS_ALPHA,
|
||||
solid: true,
|
||||
visible: true,
|
||||
ignoreRayIntersection: true,
|
||||
drawInFront: false,
|
||||
parentID: MyAvatar.sessionUUID,
|
||||
parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ?
|
||||
"_CONTROLLER_RIGHTHAND" :
|
||||
"_CONTROLLER_LEFTHAND")
|
||||
};
|
||||
this.stylus = Overlays.addOverlay("cube", stylusProperties);
|
||||
};
|
||||
|
||||
this.hideStylus = function() {
|
||||
if (!this.stylus) {
|
||||
return;
|
||||
}
|
||||
print("HIDE");
|
||||
Overlays.deleteOverlay(this.stylus);
|
||||
this.stylus = null;
|
||||
Overlays.deleteOverlay(this.stylusTip);
|
||||
this.stylusTip = null;
|
||||
};
|
||||
|
||||
this.overlayLineOn = function(closePoint, farPoint, color) {
|
||||
if (this.overlayLine === null) {
|
||||
var lineProperties = {
|
||||
|
@ -1064,7 +1128,6 @@ function MyController(hand) {
|
|||
_this.rawSecondaryValue = value;
|
||||
|
||||
// The value to check if we will allow the release function to be called
|
||||
var allowReleaseValue = 0.1;
|
||||
if (value > 0 && _this.state == STATE_HOLD) {
|
||||
_this.release();
|
||||
}
|
||||
|
@ -1162,6 +1225,142 @@ function MyController(hand) {
|
|||
this.grabPointIntersectsEntity = false;
|
||||
this.grabPointSphereOff();
|
||||
}
|
||||
|
||||
var rayPickInfo = this.calcRayPickInfo(this.hand);
|
||||
if (rayPickInfo.overlayID && rayPickInfo.distance < WEB_DISPLAY_STYLUS_DISTANCE) {
|
||||
this.showStylus();
|
||||
this.hideStylusCounter = 0;
|
||||
} else if (rayPickInfo.entityID &&
|
||||
rayPickInfo.properties.type == "Web" &&
|
||||
rayPickInfo.distance < WEB_DISPLAY_STYLUS_DISTANCE) {
|
||||
this.showStylus();
|
||||
this.hideStylusCounter = 0;
|
||||
} else {
|
||||
this.hideStylusCounter++;
|
||||
if (this.hideStylusCounter > 10) {
|
||||
this.hideStylus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (rayPickInfo.distance < WEB_TOUCH_DISTANCE) {
|
||||
Controller.triggerHapticPulse(1, 20, this.hand);
|
||||
var pointerEvent;
|
||||
|
||||
if (rayPickInfo.entityID && Entities.wantsHandControllerPointerEvents(rayPickInfo.entityID)) {
|
||||
var entity = rayPickInfo.entityID;
|
||||
var name = entityPropertiesCache.getProps(entity).name;
|
||||
|
||||
if (Entities.keyboardFocusEntity != entity) {
|
||||
Overlays.keyboardFocusOverlay = 0;
|
||||
Entities.keyboardFocusEntity = entity;
|
||||
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: this.hand + 1, // 0 is reserved for hardware mouse
|
||||
pos2D: projectOntoEntityXYPlane(entity, rayPickInfo.intersection),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.normal,
|
||||
direction: rayPickInfo.searchRay.direction,
|
||||
button: "None"
|
||||
};
|
||||
|
||||
this.hoverEntity = entity;
|
||||
Entities.sendHoverEnterEntity(entity, pointerEvent);
|
||||
}
|
||||
|
||||
// send mouse events for button highlights and tooltips.
|
||||
if (this.hand == mostRecentSearchingHand || (this.hand !== mostRecentSearchingHand &&
|
||||
this.getOtherHandController().state !== STATE_SEARCHING &&
|
||||
this.getOtherHandController().state !== STATE_ENTITY_TOUCHING &&
|
||||
this.getOtherHandController().state !== STATE_OVERLAY_TOUCHING)) {
|
||||
|
||||
// most recently searching hand has priority over other hand, for the purposes of button highlighting.
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: this.hand + 1, // 0 is reserved for hardware mouse
|
||||
pos2D: projectOntoEntityXYPlane(entity, rayPickInfo.intersection),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.normal,
|
||||
direction: rayPickInfo.searchRay.direction,
|
||||
button: "None"
|
||||
};
|
||||
|
||||
Entities.sendMouseMoveOnEntity(entity, pointerEvent);
|
||||
Entities.sendHoverOverEntity(entity, pointerEvent);
|
||||
}
|
||||
|
||||
if (!isEditing()) {
|
||||
this.grabbedEntity = entity;
|
||||
this.setState(STATE_ENTITY_TOUCHING, "begin touching entity '" + name + "'");
|
||||
return;
|
||||
}
|
||||
} else if (this.hoverEntity) {
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: this.hand + 1
|
||||
};
|
||||
Entities.sendHoverLeaveEntity(this.hoverEntity, pointerEvent);
|
||||
this.hoverEntity = null;
|
||||
}
|
||||
|
||||
if (rayPickInfo.overlayID) {
|
||||
var overlay = rayPickInfo.overlayID;
|
||||
|
||||
if (Overlays.keyboardFocusOverlay != overlay) {
|
||||
Entities.keyboardFocusEntity = null;
|
||||
Overlays.keyboardFocusOverlay = overlay;
|
||||
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: HARDWARE_MOUSE_ID,
|
||||
pos2D: projectOntoOverlayXYPlane(overlay, rayPickInfo.intersection),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.normal,
|
||||
direction: rayPickInfo.searchRay.direction,
|
||||
button: "None"
|
||||
};
|
||||
|
||||
this.hoverOverlay = overlay;
|
||||
Overlays.sendHoverEnterOverlay(overlay, pointerEvent);
|
||||
}
|
||||
|
||||
// Send mouse events for button highlights and tooltips.
|
||||
if (this.hand == mostRecentSearchingHand || (this.hand !== mostRecentSearchingHand &&
|
||||
this.getOtherHandController().state !== STATE_SEARCHING &&
|
||||
this.getOtherHandController().state !== STATE_ENTITY_TOUCHING &&
|
||||
this.getOtherHandController().state !== STATE_OVERLAY_TOUCHING)) {
|
||||
|
||||
// most recently searching hand has priority over other hand, for the purposes of button highlighting.
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: HARDWARE_MOUSE_ID,
|
||||
pos2D: projectOntoOverlayXYPlane(overlay, rayPickInfo.intersection),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.normal,
|
||||
direction: rayPickInfo.searchRay.direction,
|
||||
button: "None"
|
||||
};
|
||||
|
||||
Overlays.sendMouseMoveOnOverlay(overlay, pointerEvent);
|
||||
Overlays.sendHoverOverOverlay(overlay, pointerEvent);
|
||||
}
|
||||
|
||||
if (!isEditing()) {
|
||||
this.grabbedOverlay = overlay;
|
||||
this.setState(STATE_OVERLAY_TOUCHING, "begin touching overlay '" + overlay + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (this.hoverOverlay) {
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: HARDWARE_MOUSE_ID
|
||||
};
|
||||
Overlays.sendHoverLeaveOverlay(this.hoverOverlay, pointerEvent);
|
||||
this.hoverOverlay = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.clearEquipHaptics = function() {
|
||||
|
@ -1230,7 +1429,8 @@ function MyController(hand) {
|
|||
searchRay: pickRay,
|
||||
distance: Vec3.distance(pickRay.origin, intersection.intersection),
|
||||
intersection: intersection.intersection,
|
||||
normal: intersection.surfaceNormal
|
||||
normal: intersection.surfaceNormal,
|
||||
properties: intersection.properties
|
||||
};
|
||||
} else {
|
||||
return result;
|
||||
|
@ -1562,63 +1762,7 @@ function MyController(hand) {
|
|||
}
|
||||
}
|
||||
|
||||
var pointerEvent;
|
||||
if (rayPickInfo.entityID && Entities.wantsHandControllerPointerEvents(rayPickInfo.entityID)) {
|
||||
entity = rayPickInfo.entityID;
|
||||
name = entityPropertiesCache.getProps(entity).name;
|
||||
|
||||
if (Entities.keyboardFocusEntity != entity) {
|
||||
Overlays.keyboardFocusOverlay = 0;
|
||||
Entities.keyboardFocusEntity = entity;
|
||||
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: this.hand + 1, // 0 is reserved for hardware mouse
|
||||
pos2D: projectOntoEntityXYPlane(entity, rayPickInfo.intersection),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.normal,
|
||||
direction: rayPickInfo.searchRay.direction,
|
||||
button: "None"
|
||||
};
|
||||
|
||||
this.hoverEntity = entity;
|
||||
Entities.sendHoverEnterEntity(entity, pointerEvent);
|
||||
}
|
||||
|
||||
// send mouse events for button highlights and tooltips.
|
||||
if (this.hand == mostRecentSearchingHand || (this.hand !== mostRecentSearchingHand &&
|
||||
this.getOtherHandController().state !== STATE_SEARCHING &&
|
||||
this.getOtherHandController().state !== STATE_ENTITY_TOUCHING &&
|
||||
this.getOtherHandController().state !== STATE_OVERLAY_TOUCHING)) {
|
||||
|
||||
// most recently searching hand has priority over other hand, for the purposes of button highlighting.
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: this.hand + 1, // 0 is reserved for hardware mouse
|
||||
pos2D: projectOntoEntityXYPlane(entity, rayPickInfo.intersection),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.normal,
|
||||
direction: rayPickInfo.searchRay.direction,
|
||||
button: "None"
|
||||
};
|
||||
|
||||
Entities.sendMouseMoveOnEntity(entity, pointerEvent);
|
||||
Entities.sendHoverOverEntity(entity, pointerEvent);
|
||||
}
|
||||
|
||||
if (this.triggerSmoothedGrab() && (!isEditing() || name == "WebTablet Web")) {
|
||||
this.grabbedEntity = entity;
|
||||
this.setState(STATE_ENTITY_TOUCHING, "begin touching entity '" + name + "'");
|
||||
return;
|
||||
}
|
||||
} else if (this.hoverEntity) {
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: this.hand + 1
|
||||
};
|
||||
Entities.sendHoverLeaveEntity(this.hoverEntity, pointerEvent);
|
||||
this.hoverEntity = null;
|
||||
}
|
||||
// web-entity mouse event stuff was here
|
||||
|
||||
if (rayPickInfo.entityID) {
|
||||
entity = rayPickInfo.entityID;
|
||||
|
@ -1642,64 +1786,7 @@ function MyController(hand) {
|
|||
}
|
||||
}
|
||||
|
||||
var overlay;
|
||||
|
||||
if (rayPickInfo.overlayID) {
|
||||
overlay = rayPickInfo.overlayID;
|
||||
|
||||
if (Overlays.keyboardFocusOverlay != overlay) {
|
||||
Entities.keyboardFocusEntity = null;
|
||||
Overlays.keyboardFocusOverlay = overlay;
|
||||
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: HARDWARE_MOUSE_ID,
|
||||
pos2D: projectOntoOverlayXYPlane(overlay, rayPickInfo.intersection),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.normal,
|
||||
direction: rayPickInfo.searchRay.direction,
|
||||
button: "None"
|
||||
};
|
||||
|
||||
this.hoverOverlay = overlay;
|
||||
Overlays.sendHoverEnterOverlay(overlay, pointerEvent);
|
||||
}
|
||||
|
||||
// Send mouse events for button highlights and tooltips.
|
||||
if (this.hand == mostRecentSearchingHand || (this.hand !== mostRecentSearchingHand &&
|
||||
this.getOtherHandController().state !== STATE_SEARCHING &&
|
||||
this.getOtherHandController().state !== STATE_ENTITY_TOUCHING &&
|
||||
this.getOtherHandController().state !== STATE_OVERLAY_TOUCHING)) {
|
||||
|
||||
// most recently searching hand has priority over other hand, for the purposes of button highlighting.
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: HARDWARE_MOUSE_ID,
|
||||
pos2D: projectOntoOverlayXYPlane(overlay, rayPickInfo.intersection),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.normal,
|
||||
direction: rayPickInfo.searchRay.direction,
|
||||
button: "None"
|
||||
};
|
||||
|
||||
Overlays.sendMouseMoveOnOverlay(overlay, pointerEvent);
|
||||
Overlays.sendHoverOverOverlay(overlay, pointerEvent);
|
||||
}
|
||||
|
||||
if (this.triggerSmoothedGrab() && !isEditing()) {
|
||||
this.grabbedOverlay = overlay;
|
||||
this.setState(STATE_OVERLAY_TOUCHING, "begin touching overlay '" + overlay + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (this.hoverOverlay) {
|
||||
pointerEvent = {
|
||||
type: "Move",
|
||||
id: HARDWARE_MOUSE_ID
|
||||
};
|
||||
Overlays.sendHoverLeaveOverlay(this.hoverOverlay, pointerEvent);
|
||||
this.hoverOverlay = null;
|
||||
}
|
||||
// overlay mouse event stuff was here
|
||||
|
||||
this.updateEquipHaptics(potentialEquipHotspot, handPosition);
|
||||
|
||||
|
@ -2459,16 +2546,16 @@ function MyController(hand) {
|
|||
|
||||
entityPropertiesCache.addEntity(this.grabbedEntity);
|
||||
|
||||
if (!this.triggerSmoothedGrab()) {
|
||||
this.setState(STATE_OFF, "released trigger");
|
||||
return;
|
||||
}
|
||||
|
||||
// test for intersection between controller laser and web entity plane.
|
||||
var intersectInfo = handLaserIntersectEntity(this.grabbedEntity,
|
||||
getControllerWorldLocation(this.handToController(), true));
|
||||
if (intersectInfo) {
|
||||
|
||||
if (intersectInfo.distance > WEB_TOUCH_DISTANCE) {
|
||||
this.setState(STATE_OFF, "pulled away from web entity");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Entities.keyboardFocusEntity != this.grabbedEntity) {
|
||||
Overlays.keyboardFocusOverlay = 0;
|
||||
Entities.keyboardFocusEntity = this.grabbedEntity;
|
||||
|
@ -2495,9 +2582,6 @@ function MyController(hand) {
|
|||
}
|
||||
|
||||
this.intersectionDistance = intersectInfo.distance;
|
||||
if (farGrabEnabled) {
|
||||
this.searchIndicatorOn(intersectInfo.searchRay);
|
||||
}
|
||||
Reticle.setVisible(false);
|
||||
} else {
|
||||
this.setState(STATE_OFF, "grabbed entity was destroyed");
|
||||
|
@ -2562,16 +2646,16 @@ function MyController(hand) {
|
|||
this.overlayTouching = function (dt) {
|
||||
this.touchingEnterTimer += dt;
|
||||
|
||||
if (!this.triggerSmoothedGrab()) {
|
||||
this.setState(STATE_OFF, "released trigger");
|
||||
return;
|
||||
}
|
||||
|
||||
// Test for intersection between controller laser and Web overlay plane.
|
||||
var intersectInfo =
|
||||
handLaserIntersectOverlay(this.grabbedOverlay, getControllerWorldLocation(this.handToController(), true));
|
||||
if (intersectInfo) {
|
||||
|
||||
if (intersectInfo.distance > WEB_TOUCH_DISTANCE) {
|
||||
this.setState(STATE_OFF, "pulled away from overlay");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Overlays.keyboardFocusOverlay != this.grabbedOverlay) {
|
||||
Entities.keyboardFocusEntity = null;
|
||||
Overlays.keyboardFocusOverlay = this.grabbedOverlay;
|
||||
|
@ -2591,15 +2675,13 @@ function MyController(hand) {
|
|||
var POINTER_PRESS_TO_MOVE_DELAY = 0.15; // seconds
|
||||
var POINTER_PRESS_TO_MOVE_DEADSPOT_ANGLE = 0.05; // radians ~ 3 degrees
|
||||
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
|
||||
angleBetween(pointerEvent.direction, this.touchingEnterPointerEvent.direction) > POINTER_PRESS_TO_MOVE_DEADSPOT_ANGLE) {
|
||||
angleBetween(pointerEvent.direction,
|
||||
this.touchingEnterPointerEvent.direction) > POINTER_PRESS_TO_MOVE_DEADSPOT_ANGLE) {
|
||||
Overlays.sendMouseMoveOnOverlay(this.grabbedOverlay, pointerEvent);
|
||||
this.deadspotExpired = true;
|
||||
}
|
||||
|
||||
this.intersectionDistance = intersectInfo.distance;
|
||||
if (farGrabEnabled) {
|
||||
this.searchIndicatorOn(intersectInfo.searchRay);
|
||||
}
|
||||
Reticle.setVisible(false);
|
||||
} else {
|
||||
this.setState(STATE_OFF, "grabbed overlay was destroyed");
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
Script.scriptEnding.connect(function () {
|
||||
tablet.removeButton(button);
|
||||
button.clicked.disconnect(onClicked);
|
||||
});
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
||||
|
|
Loading…
Reference in a new issue