Easier to click buttons on web entities with shaky hand controllers

There is an angular and time dead spot on webEntity for scrolling vs clicking.
Currently, it's 150 ms and 3 degrees.  See POINTER_PRESS_TO_MOVE_DELAY and POINTER_PRESS_TO_MOVE_DEADSPOT_ANGLE

* Fix for warnings when clicking on window.open() links in WebEntity
This commit is contained in:
Anthony J. Thibault 2016-08-19 15:25:46 -07:00
parent 6be737993e
commit b2dff8aa77
4 changed files with 49 additions and 19 deletions

View file

@ -55,9 +55,11 @@ WebEngineView {
}
onNewViewRequested:{
if (desktop) {
var component = Qt.createComponent("../Browser.qml");
var newWindow = component.createObject(desktop);
request.openIn(newWindow.webView)
request.openIn(newWindow.webView);
}
}
// This breaks the webchannel used for passing messages. Fixed in Qt 5.6

View file

@ -11,6 +11,7 @@
#include <QMouseEvent>
#include <QQuickItem>
#include <QQuickWindow>
#include <QQmlContext>
#include <QOpenGLContext>
#include <glm/gtx/quaternion.hpp>
@ -68,6 +69,7 @@ bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
_webSurface->load("WebView.qml");
_webSurface->resume();
_webSurface->getRootItem()->setProperty("url", _sourceUrl);
_webSurface->getRootContext()->setContextProperty("desktop", QVariant());
_connection = QObject::connect(_webSurface, &OffscreenQmlSurface::textureUpdated, [&](GLuint textureId) {
_texture = textureId;
});

View file

@ -234,6 +234,10 @@ CONTROLLER_STATE_MACHINE[STATE_ENTITY_TOUCHING] = {
updateMethod: "entityTouching"
};
function angleBetween(a, b) {
return Math.acos(Vec3.dot(Vec3.normalize(a), Vec3.normalize(b)));
}
function projectOntoEntityXYPlane(entityID, worldPos) {
var props = entityPropertiesCache.getProps(entityID);
var invRot = Quat.inverse(props.rotation);
@ -1975,7 +1979,8 @@ function MyController(hand) {
var handPosition = this.getHandPosition();
// the center of the equipped object being far from the hand isn't enough to auto-unequip -- we also
// need to fail the findEntities test.
var nearPickedCandidateEntities = Entities.findEntities(handPosition, NEAR_GRAB_RADIUS);
var TEAR_AWAY_DISTANCE = 0.04;
var nearPickedCandidateEntities = Entities.findEntities(handPosition, NEAR_GRAB_RADIUS + TEAR_AWAY_DISTANCE);
if (nearPickedCandidateEntities.indexOf(this.grabbedEntity) == -1) {
// for whatever reason, the held/equipped entity has been pulled away. ungrab or unequip.
print("handControllerGrab -- autoreleasing held or equipped item because it is far from hand." +
@ -2128,6 +2133,11 @@ function MyController(hand) {
Entities.sendMousePressOnEntity(this.grabbedEntity, pointerEvent);
Entities.sendClickDownOnEntity(this.grabbedEntity, pointerEvent);
this.touchingEnterTimer = 0;
this.touchingEnterPointerEvent = pointerEvent;
this.touchingEnterPointerEvent.button = "None";
this.deadspotExpired = false;
}
};
@ -2135,27 +2145,37 @@ function MyController(hand) {
// test for intersection between controller laser and web entity plane.
var intersectInfo = handLaserIntersectEntity(this.grabbedEntity, this.hand);
if (intersectInfo) {
var pointerEvent = {
type: "Release",
id: this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(this.grabbedEntity, intersectInfo.point),
pos3D: intersectInfo.point,
normal: intersectInfo.normal,
direction: intersectInfo.searchRay.direction,
button: "Primary",
isPrimaryButton: true,
isSecondaryButton: false,
isTertiaryButton: false
};
var pointerEvent;
if (this.deadspotExpired) {
pointerEvent = {
type: "Release",
id: this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(this.grabbedEntity, intersectInfo.point),
pos3D: intersectInfo.point,
normal: intersectInfo.normal,
direction: intersectInfo.searchRay.direction,
button: "Primary",
isPrimaryButton: false,
isSecondaryButton: false,
isTertiaryButton: false
};
} else {
pointerEvent = this.touchingEnterPointerEvent;
pointerEvent.button = "Primary";
pointerEvent.isPrimaryButton = false;
}
Entities.sendMouseReleaseOnEntity(this.grabbedEntity, pointerEvent);
Entities.sendClickReleaseOnEntity(this.grabbedEntity, pointerEvent);
Entities.sendHoverLeaveEntity(this.grabbedEntity, pointerEvent);
this.focusedEntity = null;
}
this.focusedEntity = null;
};
this.entityTouching = function() {
this.entityTouching = function(dt) {
this.touchingEnterTimer += dt;
entityPropertiesCache.addEntity(this.grabbedEntity);
if (!this.triggerSmoothedGrab()) {
@ -2184,8 +2204,14 @@ function MyController(hand) {
isTertiaryButton: false
};
Entities.sendMouseMoveOnEntity(this.grabbedEntity, pointerEvent);
Entities.sendHoldingClickOnEntity(this.grabbedEntity, pointerEvent);
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) {
Entities.sendMouseMoveOnEntity(this.grabbedEntity, pointerEvent);
Entities.sendHoldingClickOnEntity(this.grabbedEntity, pointerEvent);
this.deadspotExpired = true;
}
this.intersectionDistance = intersectInfo.distance;
this.searchIndicatorOn(intersectInfo.searchRay);

View file

@ -121,7 +121,7 @@ function ignoreMouseActivity() {
return true;
}
var pos = Reticle.position;
if (pos.x == -1 && pos.y == -1) {
if (!pos || (pos.x == -1 && pos.y == -1)) {
return true;
}
// Only we know if we moved it, which is why this script has to replace depthReticle.js