mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 12:37:51 +02:00
Merge pull request #9449 from hyperlogic/tablet-ui
Can now use mouse to move tablet in 2D desktop mode.
This commit is contained in:
commit
eb169abdd7
2 changed files with 105 additions and 10 deletions
|
@ -2719,6 +2719,8 @@ function MyController(hand) {
|
||||||
Entities.sendClickReleaseOnEntity(this.grabbedEntity, pointerEvent);
|
Entities.sendClickReleaseOnEntity(this.grabbedEntity, pointerEvent);
|
||||||
Entities.sendHoverLeaveEntity(this.grabbedEntity, pointerEvent);
|
Entities.sendHoverLeaveEntity(this.grabbedEntity, pointerEvent);
|
||||||
}
|
}
|
||||||
|
this.grabbedEntity = null;
|
||||||
|
this.grabbedOverlay = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.entityTouching = function(dt) {
|
this.entityTouching = function(dt) {
|
||||||
|
@ -2728,7 +2730,6 @@ function MyController(hand) {
|
||||||
entityPropertiesCache.addEntity(this.grabbedEntity);
|
entityPropertiesCache.addEntity(this.grabbedEntity);
|
||||||
|
|
||||||
if (this.state == STATE_ENTITY_LASER_TOUCHING && !this.triggerSmoothedGrab()) {
|
if (this.state == STATE_ENTITY_LASER_TOUCHING && !this.triggerSmoothedGrab()) {
|
||||||
this.grabbedEntity = null;
|
|
||||||
this.setState(STATE_OFF, "released trigger");
|
this.setState(STATE_OFF, "released trigger");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2740,7 +2741,6 @@ function MyController(hand) {
|
||||||
|
|
||||||
if (this.state == STATE_ENTITY_STYLUS_TOUCHING &&
|
if (this.state == STATE_ENTITY_STYLUS_TOUCHING &&
|
||||||
intersectInfo.distance > WEB_STYLUS_LENGTH / 2.0 + WEB_TOUCH_Y_OFFSET) {
|
intersectInfo.distance > WEB_STYLUS_LENGTH / 2.0 + WEB_TOUCH_Y_OFFSET) {
|
||||||
this.grabbedEntity = null;
|
|
||||||
this.setState(STATE_OFF, "pulled away from web entity");
|
this.setState(STATE_OFF, "pulled away from web entity");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2837,19 +2837,19 @@ function MyController(hand) {
|
||||||
Overlays.sendMouseReleaseOnOverlay(this.grabbedOverlay, pointerEvent);
|
Overlays.sendMouseReleaseOnOverlay(this.grabbedOverlay, pointerEvent);
|
||||||
Overlays.sendHoverLeaveOverlay(this.grabbedOverlay, pointerEvent);
|
Overlays.sendHoverLeaveOverlay(this.grabbedOverlay, pointerEvent);
|
||||||
}
|
}
|
||||||
|
this.grabbedEntity = null;
|
||||||
|
this.grabbedOverlay = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.overlayTouching = function (dt) {
|
this.overlayTouching = function (dt) {
|
||||||
this.touchingEnterTimer += dt;
|
this.touchingEnterTimer += dt;
|
||||||
|
|
||||||
if (this.state == STATE_OVERLAY_STYLUS_TOUCHING && this.triggerSmoothedSqueezed()) {
|
if (this.state == STATE_OVERLAY_STYLUS_TOUCHING && this.triggerSmoothedSqueezed()) {
|
||||||
this.grabbedEntity = null;
|
|
||||||
this.setState(STATE_OFF, "trigger squeezed");
|
this.setState(STATE_OFF, "trigger squeezed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state == STATE_OVERLAY_LASER_TOUCHING && !this.triggerSmoothedGrab()) {
|
if (this.state == STATE_OVERLAY_LASER_TOUCHING && !this.triggerSmoothedGrab()) {
|
||||||
this.grabbedEntity = null;
|
|
||||||
this.setState(STATE_OFF, "released trigger");
|
this.setState(STATE_OFF, "released trigger");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,12 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
/* global getControllerWorldLocation, setEntityCustomData, Tablet, WebTablet:true, HMD, Settings, Script, Vec3, Quat, MyAvatar, Entities, Overlays, Camera, Messages */
|
/* global getControllerWorldLocation, setEntityCustomData, Tablet, WebTablet:true, HMD, Settings, Script,
|
||||||
|
Vec3, Quat, MyAvatar, Entities, Overlays, Camera, Messages, Xform */
|
||||||
|
|
||||||
Script.include(Script.resolvePath("../libraries/utils.js"));
|
Script.include(Script.resolvePath("../libraries/utils.js"));
|
||||||
Script.include(Script.resolvePath("../libraries/controllers.js"));
|
Script.include(Script.resolvePath("../libraries/controllers.js"));
|
||||||
|
Script.include(Script.resolvePath("../libraries/Xform.js"));
|
||||||
|
|
||||||
var X_AXIS = {x: 1, y: 0, z: 0};
|
var X_AXIS = {x: 1, y: 0, z: 0};
|
||||||
var Y_AXIS = {x: 0, y: 1, z: 0};
|
var Y_AXIS = {x: 0, y: 1, z: 0};
|
||||||
|
@ -56,11 +58,11 @@ function calcSpawnInfo(hand, height) {
|
||||||
rotation: lookAtRot
|
rotation: lookAtRot
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
var front = Quat.getFront(MyAvatar.orientation);
|
var front = Quat.getFront(Camera.orientation);
|
||||||
finalPosition = Vec3.sum(Vec3.sum(MyAvatar.position, Vec3.multiply(0.6, front)), {x: 0, y: 0.6, z: 0});
|
finalPosition = Vec3.sum(Camera.position, Vec3.multiply(0.6, front));
|
||||||
return {
|
return {
|
||||||
position: finalPosition,
|
position: finalPosition,
|
||||||
rotation: Quat.lookAt(finalPosition, MyAvatar.getHeadPosition(), Y_AXIS)
|
rotation: Quat.multiply(Camera.orientation, {x: 0, y: 1, z: 0, w: 0})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,6 +150,28 @@ WebTablet = function (url, width, dpi, hand, clientOnly) {
|
||||||
_this.onHmdChanged();
|
_this.onHmdChanged();
|
||||||
};
|
};
|
||||||
HMD.displayModeChanged.connect(this.myOnHmdChanged);
|
HMD.displayModeChanged.connect(this.myOnHmdChanged);
|
||||||
|
|
||||||
|
this.myMousePressEvent = function (event) {
|
||||||
|
_this.mousePressEvent(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.myMouseMoveEvent = function (event) {
|
||||||
|
_this.mouseMoveEvent(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.myMouseReleaseEvent = function (event) {
|
||||||
|
_this.mouseReleaseEvent(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!HMD.active) {
|
||||||
|
Controller.mousePressEvent.connect(this.myMousePressEvent);
|
||||||
|
Controller.mouseMoveEvent.connect(this.myMouseMoveEvent);
|
||||||
|
Controller.mouseReleaseEvent.connect(this.myMouseReleaseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dragging = false;
|
||||||
|
this.initialLocalIntersectionPoint = {x: 0, y: 0, z: 0};
|
||||||
|
this.initialLocalPosition = {x: 0, y: 0, z: 0};
|
||||||
};
|
};
|
||||||
|
|
||||||
WebTablet.prototype.setURL = function (url) {
|
WebTablet.prototype.setURL = function (url) {
|
||||||
|
@ -167,6 +191,12 @@ WebTablet.prototype.destroy = function () {
|
||||||
Entities.deleteEntity(this.tabletEntityID);
|
Entities.deleteEntity(this.tabletEntityID);
|
||||||
Entities.deleteEntity(this.homeButtonEntity);
|
Entities.deleteEntity(this.homeButtonEntity);
|
||||||
HMD.displayModeChanged.disconnect(this.myOnHmdChanged);
|
HMD.displayModeChanged.disconnect(this.myOnHmdChanged);
|
||||||
|
|
||||||
|
if (HMD.active) {
|
||||||
|
Controller.mousePressEvent.disconnect(this.myMousePressEvent);
|
||||||
|
Controller.mouseMoveEvent.disconnect(this.myMouseMoveEvent);
|
||||||
|
Controller.mouseReleaseEvent.disconnect(this.myMouseReleaseEvent);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// calclulate the appropriate position of the tablet in world space, such that it fits in the center of the screen.
|
// calclulate the appropriate position of the tablet in world space, such that it fits in the center of the screen.
|
||||||
|
@ -203,6 +233,17 @@ WebTablet.prototype.calculateTabletAttachmentProperties = function (hand, tablet
|
||||||
};
|
};
|
||||||
|
|
||||||
WebTablet.prototype.onHmdChanged = function () {
|
WebTablet.prototype.onHmdChanged = function () {
|
||||||
|
|
||||||
|
if (HMD.active) {
|
||||||
|
Controller.mousePressEvent.disconnect(this.myMousePressEvent);
|
||||||
|
Controller.mouseMoveEvent.disconnect(this.myMouseMoveEvent);
|
||||||
|
Controller.mouseReleaseEvent.disconnect(this.myMouseReleaseEvent);
|
||||||
|
} else {
|
||||||
|
Controller.mousePressEvent.connect(this.myMousePressEvent);
|
||||||
|
Controller.mouseMoveEvent.connect(this.myMouseMoveEvent);
|
||||||
|
Controller.mouseReleaseEvent.connect(this.myMouseReleaseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
var NO_HANDS = -1;
|
var NO_HANDS = -1;
|
||||||
var tabletProperties = {};
|
var tabletProperties = {};
|
||||||
// compute position, rotation & parentJointIndex of the tablet
|
// compute position, rotation & parentJointIndex of the tablet
|
||||||
|
@ -224,7 +265,7 @@ WebTablet.prototype.cleanUpOldTabletsOnJoint = function(jointIndex) {
|
||||||
print("cleanup " + children);
|
print("cleanup " + children);
|
||||||
children.forEach(function(childID) {
|
children.forEach(function(childID) {
|
||||||
var props = Entities.getEntityProperties(childID, ["name"]);
|
var props = Entities.getEntityProperties(childID, ["name"]);
|
||||||
if (props.name == "WebTablet Tablet") {
|
if (props.name === "WebTablet Tablet") {
|
||||||
print("cleaning up " + props.name);
|
print("cleaning up " + props.name);
|
||||||
Entities.deleteEntity(childID);
|
Entities.deleteEntity(childID);
|
||||||
} else {
|
} else {
|
||||||
|
@ -238,7 +279,7 @@ WebTablet.prototype.cleanUpOldTablets = function() {
|
||||||
this.cleanUpOldTabletsOnJoint(SENSOR_TO_ROOM_MATRIX);
|
this.cleanUpOldTabletsOnJoint(SENSOR_TO_ROOM_MATRIX);
|
||||||
this.cleanUpOldTabletsOnJoint(CAMERA_MATRIX);
|
this.cleanUpOldTabletsOnJoint(CAMERA_MATRIX);
|
||||||
this.cleanUpOldTabletsOnJoint(65529);
|
this.cleanUpOldTabletsOnJoint(65529);
|
||||||
}
|
};
|
||||||
|
|
||||||
WebTablet.prototype.unregister = function() {
|
WebTablet.prototype.unregister = function() {
|
||||||
Messages.unsubscribe("home");
|
Messages.unsubscribe("home");
|
||||||
|
@ -257,3 +298,57 @@ WebTablet.unpickle = function (string) {
|
||||||
WebTablet.prototype.getPosition = function () {
|
WebTablet.prototype.getPosition = function () {
|
||||||
return Overlays.getProperty(this.webOverlayID, "position");
|
return Overlays.getProperty(this.webOverlayID, "position");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
WebTablet.prototype.mousePressEvent = function (event) {
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
var entityPickResults = Entities.findRayIntersection(pickRay, true); // non-accurate picking
|
||||||
|
if (entityPickResults.intersects && entityPickResults.entityID === this.tabletEntityID) {
|
||||||
|
var overlayPickResults = Overlays.findRayIntersection(pickRay);
|
||||||
|
if (!overlayPickResults.intersects || !overlayPickResults.overlayID === this.webOverlayID) {
|
||||||
|
this.dragging = true;
|
||||||
|
var invCameraXform = new Xform(Camera.orientation, Camera.position).inv();
|
||||||
|
this.initialLocalIntersectionPoint = invCameraXform.xformPoint(entityPickResults.intersection);
|
||||||
|
this.initialLocalPosition = Entities.getEntityProperties(this.tabletEntityID, ["localPosition"]).localPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function rayIntersectPlane(planePosition, planeNormal, rayStart, rayDirection) {
|
||||||
|
var rayDirectionDotPlaneNormal = Vec3.dot(rayDirection, planeNormal);
|
||||||
|
if (rayDirectionDotPlaneNormal > 0.00001 || rayDirectionDotPlaneNormal < -0.00001) {
|
||||||
|
var rayStartDotPlaneNormal = Vec3.dot(Vec3.subtract(planePosition, rayStart), planeNormal);
|
||||||
|
var distance = rayStartDotPlaneNormal / rayDirectionDotPlaneNormal;
|
||||||
|
return {hit: true, distance: distance};
|
||||||
|
} else {
|
||||||
|
// ray is parallel to the plane
|
||||||
|
return {hit: false, distance: 0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WebTablet.prototype.mouseMoveEvent = function (event) {
|
||||||
|
if (this.dragging) {
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
|
||||||
|
// transform pickRay into camera local coordinates
|
||||||
|
var invCameraXform = new Xform(Camera.orientation, Camera.position).inv();
|
||||||
|
var localPickRay = {
|
||||||
|
origin: invCameraXform.xformPoint(pickRay.origin),
|
||||||
|
direction: invCameraXform.xformVector(pickRay.direction)
|
||||||
|
};
|
||||||
|
|
||||||
|
var NORMAL = {x: 0, y: 0, z: -1};
|
||||||
|
var result = rayIntersectPlane(this.initialLocalIntersectionPoint, NORMAL, localPickRay.origin, localPickRay.direction);
|
||||||
|
if (result.hit) {
|
||||||
|
var localIntersectionPoint = Vec3.sum(localPickRay.origin, Vec3.multiply(localPickRay.direction, result.distance));
|
||||||
|
var localOffset = Vec3.subtract(localIntersectionPoint, this.initialLocalIntersectionPoint);
|
||||||
|
var localPosition = Vec3.sum(this.initialLocalPosition, localOffset);
|
||||||
|
Entities.editEntity(this.tabletEntityID, {
|
||||||
|
localPosition: localPosition
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
WebTablet.prototype.mouseReleaseEvent = function (event) {
|
||||||
|
this.dragging = false;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue