fix stylus module

This commit is contained in:
Dante Ruiz 2017-11-10 17:28:55 -08:00
parent ef55e3181d
commit 43c6d71236
7 changed files with 209 additions and 81 deletions

View file

@ -20,9 +20,9 @@ controllerDispatcherPluginsNeedSort = false;
Script.include("/~/system/libraries/utils.js");
Script.include("/~/system/libraries/controllers.js");
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
Script.include("/~/system/libraries/pointersUtils.js");
(function() {
Script.include("/~/system/libraries/pointersUtils.js");
var NEAR_MAX_RADIUS = 0.1;
var TARGET_UPDATE_HZ = 60; // 50hz good enough, but we're using update
@ -148,8 +148,8 @@ Script.include("/~/system/libraries/pointersUtils.js");
this.setIgnoreTablet = function() {
if (HMD.tabletID !== this.tabletID) {
this.tabletID = HMD.tabletID;
Pointers.setIgnoreItems(_this.leftControllerPointer, _this.blacklist.concat([HMD.tabletID]));
Pointers.setIgnoreItems(_this.rightControllerPointer, _this.blacklist.concat([HMD.tabletID]));
Pointers.setIgnoreItems(_this.leftPointer, _this.blacklist.concat([HMD.tabletID]));
Pointers.setIgnoreItems(_this.rightPointer, _this.blacklist.concat([HMD.tabletID]));
}
};
@ -239,12 +239,12 @@ Script.include("/~/system/libraries/pointersUtils.js");
// raypick for each controller
var rayPicks = [
Pointers.getPrevPickResult(_this.leftControllerPointer),
Pointers.getPrevPickResult(_this.rightControllerPointer)
Pointers.getPrevPickResult(_this.leftPointer),
Pointers.getPrevPickResult(_this.rightPointer)
];
var hudRayPicks = [
Pointers.getPrevPickResult(_this.leftControllerHudRayPick),
Pointers.getPrevPickResult(_this.rightControllerHudRayPick)
Pointers.getPrevPickResult(_this.leftHudPointer),
Pointers.getPrevPickResult(_this.rightHudPointer)
];
var mouseRayPick = RayPick.getPrevRayPickResult(_this.mouseRayPick);
// if the pickray hit something very nearby, put it into the nearby entities list
@ -324,11 +324,12 @@ Script.include("/~/system/libraries/pointersUtils.js");
// activity-slots which this plugin consumes as "in use"
_this.runningPluginNames[orderedPluginName] = true;
_this.markSlots(candidatePlugin, orderedPluginName);
_this.enableLaserForPlugin(candidatePlugin);
_this.pointerManager.makePointerVisible(candidatePlugin.parameters.handLaser);
//_this.enableLaserForPlugin(candidatePlugin);
if (DEBUG) {
print("controllerDispatcher running " + orderedPluginName);
}
}
}
if (PROFILE) {
Script.endProfileRange("dispatch.isReady." + orderedPluginName);
}
@ -360,19 +361,19 @@ Script.include("/~/system/libraries/pointersUtils.js");
// of running plugins and mark its activity-slots as "not in use"
delete _this.runningPluginNames[runningPluginName];
_this.markSlots(plugin, false);
_this.disableLaserForPlugin(plugin);
_this.pointerManager.makePointerInvisible(plugin.parameters.handLaser);
if (DEBUG) {
print("controllerDispatcher stopping " + runningPluginName);
}
}
_this.lockLaserToTarget(runningness.laserLockInfo, plugin);
_this.pointerManager.lockPointerEnd(plugin.parameters.handLaser, runningness.laserLockInfo);
if (PROFILE) {
Script.endProfileRange("dispatch.run." + runningPluginName);
}
}
}
}
_this.pointerManager.updatePoiniterRenderStates(false, 0);
_this.pointerManager.updatePointersRenderState(controllerData.triggerClicks, controllerData.triggerValues);
if (PROFILE) {
Script.endProfileRange("dispatch.run");
}
@ -397,35 +398,43 @@ Script.include("/~/system/libraries/pointersUtils.js");
Controller.enableMapping(MAPPING_NAME);
this.pointerManager.createPointer(false, PickType.Ray, {
this.leftPointer = this.pointerManager.createPointer(false, PickType.Ray, {
joint: "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
filter: Picks.PICK_OVERLAYS | Picks.PICK_ENTITIES,
triggers: [{action: Controller.Standard.LTClick, button: "Focus"}, {action: Controller.Standard.LTClick, button: "Primary"}],
posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand, true),
hover: true
hover: true,
distanceScaleEnd: true,
hand: LEFT_HAND
});
this.pointerManager.createPointer(false, PickType.Ray, {
this.rightPointer = this.pointerManager.createPointer(false, PickType.Ray, {
joint: "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND",
filter: Picks.PICK_OVERLAYS | Picks.PICK_ENTITIES,
triggers: [{action: Controller.Standard.RTClick, button: "Focus"}, {action: Controller.Standard.RTClick, button: "Primary"}],
posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand, true),
hover: true
hover: true,
distanceScaleEnd: true,
hand: RIGHT_HAND
});
this.pointerManager.createPointer(true, PickType.Ray, {
this.leftHudPointer = this.pointerManager.createPointer(true, PickType.Ray, {
joint: "_CONTROLLER_LEFTHAND",
filter: Picks.PICK_HUD,
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand, true),
triggers: [{action: Controller.Standard.LTClick, button: "Focus"}, {action: Controller.Standard.LTClick, button: "Primary"}],
hover: true
hover: true,
distanceScaleEnd: true,
hand: LEFT_HAND
});
this.pointerManager.createPointer(true, PickType.Ray, {
this.rightHudPointer = this.pointerManager.createPointer(true, PickType.Ray, {
joint: "_CONTROLLER_RIGHTHAND",
filter: Picks.PICK_HUD,
maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE,
posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand, true),
triggers: [{action: Controller.Standard.RTClick, button: "Focus"}, {action: Controller.Standard.RTClick, button: "Primary"}],
hover: true
hover: true,
distanceScaleEnd: true,
hand: RIGHT_HAND
});
this.mouseRayPick = RayPick.createRayPick({
joint: "Mouse",

View file

@ -42,10 +42,6 @@
return (this.hand === RIGHT_HAND) ? Controller.Standard.LeftHand : Controller.Standard.RightHand;
};
_this.isClicked = function() {
return _this.triggerClicked;
};
this.handToController = function() {
return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
};
@ -64,10 +60,6 @@
return point2d;
};
this.setReticlePosition = function(point2d) {
Reticle.setPosition(point2d);
};
this.pointingAtTablet = function(controllerData) {
var rayPick = controllerData.rayPicks[this.hand];
return (rayPick.objectID === HMD.tabletScreenID || rayPick.objectID === HMD.homeButtonID);
@ -84,7 +76,7 @@
if (!Window.isPointOnDesktopWindow(point2d) && !this.triggerClicked) {
return false;
}
Reticle.visible = false;
this.triggerClicked = controllerData.triggerClicks[this.hand];
return true;
};
@ -106,11 +98,6 @@
var leftHudOverlayPointer = new HudOverlayPointer(LEFT_HAND);
var rightHudOverlayPointer = new HudOverlayPointer(RIGHT_HAND);
var clickMapping = Controller.newMapping('HudOverlayPointer-click');
clickMapping.from(rightHudOverlayPointer.isClicked).to(Controller.Actions.ReticleClick);
clickMapping.from(leftHudOverlayPointer.isClicked).to(Controller.Actions.ReticleClick);
clickMapping.enable();
ControllerDispatcherUtils.enableDispatcherModule("LeftHudOverlayPointer", leftHudOverlayPointer);
ControllerDispatcherUtils.enableDispatcherModule("RightHudOverlayPointer", rightHudOverlayPointer);

View file

@ -21,6 +21,7 @@ Script.include("/~/system/libraries/utils.js");
function InEditMode(hand) {
this.hand = hand;
this.triggerClicked = false;
this.selectedTarget = null;
this.parameters = makeDispatcherModuleParameters(
160,
@ -50,23 +51,23 @@ Script.include("/~/system/libraries/utils.js");
};
this.sendPickData = function(controllerData) {
if (controllerData.triggerClicks[this.hand] && !this.triggerClicked) {
var intersection = controllerData.rayPicks[this.hand];
if (intersection.type === Picks.INTERSECTED_ENTITY) {
if (controllerData.triggerClicks[this.hand]) {
if (!this.triggerClicked) {
this.selectedTarget = controllerData.rayPicks[this.hand];
}
if (this.selectedTarget.type === Picks.INTERSECTED_ENTITY) {
Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({
method: "selectEntity",
entityID: intersection.objectID
entityID: this.selectedTarget.objectID
}));
} else if (intersection.type === Picks.INTERSECTED_OVERLAY) {
} else if (this.selectedTarget.type === Picks.INTERSECTED_OVERLAY) {
Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({
method: "selectOverlay",
overlayID: intersection.objectID
overlayID: this.selectedTarget.objectID
}));
}
this.triggerClicked = true;
} else {
this.triggerClicked = false;
}
};
@ -76,9 +77,12 @@ Script.include("/~/system/libraries/utils.js");
this.isReady = function(controllerData) {
if (isInEditMode()) {
this.triggerClicked = false;
if (controllerData.triggerValues[this.hand] < TRIGGER_ON_VALUE) {
this.triggerClicked = false;
}
return makeRunningValues(true, [], []);
}
this.triggerClicked = false;
return makeRunningValues(false, [], []);
};

View file

@ -1,6 +1,6 @@
"use strict";
// tabletStylusInput.js
// stylusInput.js
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -16,6 +16,26 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
Script.include("/~/system/libraries/controllers.js");
(function() {
var TouchEventUtils = Script.require("/~/system/libraries/touchEventUtils.js");
function isNearStylusTarget(stylusTargets, maxNormalDistance) {
var stylusTargetIDs = [];
for (var index = 0; index < stylusTargets.length; index++) {
var stylusTarget = stylusTargets[index];
if (stylusTarget.distance <= maxNormalDistance) {
stylusTargetIDs.push(stylusTarget.id);
}
}
return stylusTargetIDs;
}
function getOverlayDistance(controllerPosition, overlayID) {
var position = Overlays.getProperty(overlayID, "position");
return {
id: overlayID,
distance: Vec3.distance(position, controllerPosition)
};
}
function TabletStylusInput(hand) {
this.hand = hand;
@ -24,8 +44,15 @@ Script.include("/~/system/libraries/controllers.js");
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
[],
100);
this.pointer = Pointers.createPointer(PickType.Stylus, { hand: this.hand });
this.pointer = Pointers.createPointer(PickType.Stylus, {
hand: this.hand,
filter: Picks.PICK_OVERLAYS,
hover: true,
enabled: true
});
this.disable = false;
this.otherModuleNeedsToRun = function(controllerData) {
var grabOverlayModuleName = this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay";
@ -40,13 +67,90 @@ Script.include("/~/system/libraries/controllers.js");
this.overlayLaserActive = function(controllerData) {
var rightOverlayLaserModule = getEnabledModuleByName("RightOverlayLaserInput");
var leftOverlayLaserModule = getEnabledModuleByName("LeftOverlayLaserInput");
var rightModuleRunning = rightOverlayLaserModule ? !rightOverlayLaserModule.shouldExit(controllerData) : false;
var leftModuleRunning = leftOverlayLaserModule ? !leftOverlayLaserModule.shouldExit(controllerData) : false;
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 candidateEntities = controllerData.nearbyEntityProperties;
var candidateOverlays = controllerData.nearbyOverlayIDs;
var controllerPosition = controllerData.controllerLocations[this.hand].position;
var i, props, stylusTarget;
/*for (i = 0; i < candidateEntities.length; i++) {
props = candidateEntities[i];
if (props && props.type === "Web") {
stylusTarget = TouchEventUtils.calculateTouchTargetFromEntity({position: controllerPosition}, candidateEntities[i]);
if (stylusTarget) {
stylusTargets.push(stylusTarget);
}
}
}*/
for (i = 0; i < candidateOverlays.length; i++) {
if (candidateOverlays[i] !== HMD.tabletID &&
Overlays.getProperty(candidateOverlays[i], "visible")) {
stylusTarget = getOverlayDistance(controllerPosition, candidateOverlays[i]);
if (stylusTarget) {
stylusTargets.push(stylusTarget);
}
}
}
// add the tabletScreen, if it is valid
if (HMD.tabletScreenID && HMD.tabletScreenID !== Uuid.NULL &&
Overlays.getProperty(HMD.tabletScreenID, "visible")) {
stylusTarget = getOverlayDistance(controllerPosition, HMD.tabletScreenID);
if (stylusTarget) {
stylusTargets.push(stylusTarget);
}
}
// add the tablet home button.
if (HMD.homeButtonID && HMD.homeButtonID !== Uuid.NULL &&
Overlays.getProperty(HMD.homeButtonID, "visible")) {
stylusTarget = getOverlayDistance(controllerPosition, HMD.homeButtonID);
if (stylusTarget) {
stylusTargets.push(stylusTarget);
}
}
var WEB_DISPLAY_STYLUS_DISTANCE = 0.5;
var nearStylusTarget = isNearStylusTarget(stylusTargets, WEB_DISPLAY_STYLUS_DISTANCE * sensorScaleFactor);
if (nearStylusTarget.length !== 0) {
print(this.hand + "---" + this.disable);
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;
}
// var nearestStylusTarget = calculateNearestStylusTarget(stylusTargets);
};
this.isReady = function (controllerData) {
if (!this.overlayLaserActive(controllerData) && !this.otherModuleNeedsToRun(controllerData)) {
if (this.processStylus(controllerData)) {
return makeRunningValues(true, [], []);
} else {
return makeRunningValues(false, [], []);
@ -58,16 +162,35 @@ Script.include("/~/system/libraries/controllers.js");
};
this.cleanup = function () {
Pointers.createPointer(this.pointer);
//Pointers.createPointer(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 leftTabletStylusInput = new TabletStylusInput(LEFT_HAND);
var rightTabletStylusInput = new TabletStylusInput(RIGHT_HAND);
enableDispatcherModule("LeftTabletStylusInput", leftTabletStylusInput);
enableDispatcherModule("RightTabletStylusInput", rightTabletStylusInput);
Overlays.hoverEnterOverlay.connect(mouseHoverEnter);
Overlays.hoverLeaveOverlay.connect(mouseHoverLeave);
this.cleanup = function () {
leftTabletStylusInput.cleanup();
rightTabletStylusInput.cleanup();

View file

@ -19,7 +19,7 @@ var CONTOLLER_SCRIPTS = [
"controllerModules/nearParentGrabOverlay.js",
"controllerModules/nearActionGrabEntity.js",
"controllerModules/farActionGrabEntity.js",
//"controllerModules/tabletStylusInput.js",
"controllerModules/tabletStylusInput.js",
"controllerModules/equipEntity.js",
"controllerModules/nearTrigger.js",
"controllerModules/overlayLaserInput.js",

View file

@ -109,6 +109,10 @@ DISPATCHER_PROPERTIES = [
// requiredDataForReady -- which "situation" parts this module looks at to decide if it will start
// sleepMSBetweenRuns -- how long to wait between calls to this module's "run" method
makeDispatcherModuleParameters = function (priority, activitySlots, requiredDataForReady, sleepMSBetweenRuns, enableLaserForHand) {
if (enableLaserForHand === undefined) {
enableLaserForHand = -1;
}
return {
priority: priority,
activitySlots: activitySlots,

View file

@ -16,7 +16,8 @@
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
function Pointer(hudLayer, pickType, pointerData) {
Pointer = function(hudLayer, pickType, pointerData) {
var _this = this;
this.SEARCH_SPHERE_SIZE = 0.0132;
this.dim = {x: this.SEARCH_SPHERE_SIZE, y: this.SEARCH_SPHERE_SIZE, z: this.SEARCH_SPHERE_SIZE};
this.halfPath = {
@ -28,7 +29,7 @@ function Pointer(hudLayer, pickType, pointerData) {
glow: 1.0,
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
drawInFront: !hudLayer, // Even when burried inside of something, show it.
drawHUDLayer: hudLayer,
parentID: MyAvatar.SELF_ID
};
@ -39,7 +40,7 @@ function Pointer(hudLayer, pickType, pointerData) {
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
alpha: 0.9,
ignoreRayIntersection: true,
drawInFront: true, // Even when burried inside of something, show it.
drawInFront: !hudLayer, // Even when burried inside of something, show it.
drawHUDLayer: hudLayer,
visible: true
};
@ -52,7 +53,7 @@ function Pointer(hudLayer, pickType, pointerData) {
glow: 1.0,
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
drawInFront: !hudLayer, // Even when burried inside of something, show it.
drawHUDLayer: hudLayer,
parentID: MyAvatar.SELF_ID
};
@ -63,7 +64,7 @@ function Pointer(hudLayer, pickType, pointerData) {
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
alpha: 0.9,
ignoreRayIntersection: true,
drawInFront: true, // Even when burried inside of something, show it.
drawInFront: !hudLayer, // Even when burried inside of something, show it.
drawHUDLayer: hudLayer,
visible: true
};
@ -76,7 +77,7 @@ function Pointer(hudLayer, pickType, pointerData) {
glow: 1.0,
lineWidth: 5,
ignoreRayIntersection: true, // always ignore this
drawInFront: true, // Even when burried inside of something, show it.
drawInFront: !hudLayer, // Even when burried inside of something, show it.
drawHUDLayer: hudLayer,
parentID: MyAvatar.SELF_ID
};
@ -95,18 +96,16 @@ function Pointer(hudLayer, pickType, pointerData) {
this.pointerID = null;
this.triggers = [];
this.joint = null;
this.visible = false;
this.locked = false;
this.hand = pointerData.hand;
delete pointerData.hand;
function createPointer(pickType, pointerData) {
if (this.pointerID) {
Pointers.removePointer(this.pointerID);
}
this.pointerID = Pointers.createPointer(pickType, pointerData);
Pointers.setRenderState(this.pointerID, "");
Pointers.enablePointer(this.pointerID);
var pointerID = Pointers.createPointer(pickType, pointerData);
Pointers.setRenderState(pointerID, "");
Pointers.enablePointer(pointerID);
return pointerID;
}
this.enable = function() {
@ -125,26 +124,26 @@ function Pointer(hudLayer, pickType, pointerData) {
this.lockEnd = function(lockData) {
if (lockData !== undefined) {
var hand = lockData.hand;
if (this.visible) {
var targetID = lockData.targetID;
var targetIsOverlay = lockData.isOverlay;
Pointers.setLockEndUUID(this.pointer, targetID, targetIsOverlay);
Pointers.setLockEndUUID(this.pointerID, targetID, targetIsOverlay);
this.locked = targetID;
}
} else {
} else if (this.locked) {
Pointers.setLockEndUUID(this.pointerID, null, false);
this.locked = false;
}
};
this.updateRenderState = function(triggerClicked, triggerValue) {
this.updateRenderState = function(triggerClicks, triggerValues) {
var mode = "";
if (this.visible) {
if (this.locked) {
mode = "hold";
} else if (triggerClicked) {
} else if (triggerClicks[this.hand]) {
mode = "full";
} else if (triggerValue > TRIGGER_ON_VALUE) {
} else if (triggerValues[this.hand] > TRIGGER_ON_VALUE) {
mode = "half";
}
}
@ -152,40 +151,42 @@ function Pointer(hudLayer, pickType, pointerData) {
Pointers.setRenderState(this.pointerID, mode);
};
pointerData.renderStates = this.renderStates;
pointerData.defualtRenderStates = this.defualtRenderStates;
createPointer(pickType, pointerData);
}
pointerData.defaultRenderStates = this.defaultRenderStates;
this.pointerID = createPointer(pickType, pointerData);
print(this.pointerID);
};
function PointerManager() {
PointerManager = function() {
this.pointers = [];
this.createPointer = function(hudLayer, pickType, pointerData) {
var pointer = new Pointer(hudLayer, pickType, pointerData);
this.pointers.push(pointer);
return pointer.pointerID;
};
this.makePointerVisible = function(index) {
if (index < this.pointers.length) {
if (index < this.pointers.length && index >= 0) {
this.pointers[index].makeVisible();
}
};
this.makePointerInvisible = function(index) {
if (index < this.pointers.length) {
if (index < this.pointers.length && index >= 0) {
this.pointers[index].makeInvisible();
}
};
this.lockPointerEnd = function(index, lockData) {
if (index < this.pointers.length) {
if (index < this.pointers.length && index >= 0) {
this.pointers[index].lockEnd(lockData);
}
};
this.updatePointersRenderState = function(triggerClicked, triggerValue) {
this.updatePointersRenderState = function(triggerClicks, triggerValues) {
for (var index = 0; index < this.pointers.length; index++) {
this.pointers[index].updateRenderState(triggerClicked, triggerValue);
this.pointers[index].updateRenderState(triggerClicks, triggerValues);
}
};
}
};