trying to get near-triggering working

This commit is contained in:
Seth Alves 2017-08-15 14:14:28 -07:00
parent 1d24523be9
commit ddca25672f
6 changed files with 182 additions and 56 deletions

View file

@ -9,7 +9,7 @@
/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation, RayPick,
controllerDispatcherPlugins, controllerDispatcherPluginsNeedSort, entityIsGrabbable,
LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE
LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE, DISPATCHER_PROPERTIES
*/
controllerDispatcherPlugins = {};
@ -25,25 +25,6 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
var NEAR_MIN_RADIUS = 0.1;
var NEAR_MAX_RADIUS = 1.0;
var DISPATCHER_PROPERTIES = [
"position",
"registrationPoint",
"rotation",
"gravity",
"collidesWith",
"dynamic",
"collisionless",
"locked",
"name",
"shapeType",
"parentID",
"parentJointIndex",
"density",
"dimensions",
"userData"
];
var TARGET_UPDATE_HZ = 60; // 50hz good enough, but we're using update
var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ;
var lastInterval = Date.now();

View file

@ -18,6 +18,7 @@
COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
COLORS_GRAB_DISTANCE_HOLD,
NEAR_GRAB_RADIUS,
DISPATCHER_PROPERTIES,
Entities,
makeDispatcherModuleParameters,
makeRunningValues,
@ -34,7 +35,8 @@
projectOntoEntityXYPlane,
projectOntoOverlayXYPlane,
entityHasActions,
ensureDynamic
ensureDynamic,
findGroupParent
*/
MSECS_PER_SEC = 1000.0;
@ -72,6 +74,27 @@ NEAR_GRAB_RADIUS = 0.1;
DISPATCHER_PROPERTIES = [
"position",
"registrationPoint",
"rotation",
"gravity",
"collidesWith",
"dynamic",
"collisionless",
"locked",
"name",
"shapeType",
"parentID",
"parentJointIndex",
"density",
"dimensions",
"userData"
];
// priority -- a lower priority means the module will be asked sooner than one with a higher priority in a given update step
// activitySlots -- indicates which "slots" must not yet be in use for this module to start
// requiredDataForReady -- which "situation" parts this module looks at to decide if it will start
@ -137,6 +160,9 @@ getGrabbableData = function (props) {
if (!grabbableData.hasOwnProperty("kinematicGrab")) {
grabbableData.kinematicGrab = true;
}
if (!grabbableData.hasOwnProperty("wantsTrigger")) {
grabbableData.wantsTrigger = false;
}
return grabbableData;
};
@ -258,3 +284,17 @@ ensureDynamic = function (entityID) {
}
}
};
findGroupParent = function (controllerData, targetProps) {
while (targetProps.parentID && targetProps.parentID != NULL_UUID) {
var parentProps = Entities.getEntityProperties(targetProps.parentID, DISPATCHER_PROPERTIES);
if (!parentProps) {
break;
}
parentProps.id = targetProps.parentID;
targetProps = parentProps;
controllerData.nearbyEntityPropertiesByID[targetProps.id] = targetProps;
}
return targetProps;
};

View file

@ -9,7 +9,7 @@
getControllerJointIndex, getGrabbableData, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable,
Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues,
TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS
TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent
*/
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
@ -152,6 +152,11 @@ Script.include("/~/system/libraries/controllers.js");
break;
}
if (entityIsGrabbable(props)) {
// if we've attempted to grab a child, roll up to the root of the tree
var groupRootProps = findGroupParent(controllerData, props);
if (entityIsGrabbable(groupRootProps)) {
return groupRootProps;
}
return props;
}
}
@ -162,23 +167,18 @@ Script.include("/~/system/libraries/controllers.js");
this.targetEntityID = null;
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) {
makeRunningValues(false, [], []);
return makeRunningValues(false, [], []);
}
var targetProps = this.getTargetProps(controllerData);
if (targetProps) {
if (!propsArePhysical(targetProps)) {
// XXX make sure no highlights are enabled from this module
return makeRunningValues(false, [], []); // let nearParentGrabEntity handle it
} else {
this.targetEntityID = targetProps.id;
ContextOverlay.entityWithContextOverlay = this.targetEntityID;
ContextOverlay.enabled = true;
// XXX highlight this.targetEntityID here
return makeRunningValues(true, [this.targetEntityID], []);
}
} else {
// XXX make sure no highlights are enabled from this module
return makeRunningValues(false, [], []);
}
};
@ -204,26 +204,8 @@ Script.include("/~/system/libraries/controllers.js");
var targetProps = this.getTargetProps(controllerData);
if (targetProps) {
// XXX
var rayPickInfo = controllerData.rayPicks[this.hand];
var pointerEvent = {
type: "Move",
id: this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(rayPickInfo.entityID, rayPickInfo.intersection, targetProps),
pos3D: rayPickInfo.intersection,
normal: rayPickInfo.normal,
direction: rayPickInfo.searchRay.direction,
button: "Secondary"
};
if (ContextOverlay.createOrDestroyContextOverlay(rayPickInfo.entityID, pointerEvent)) {
}
// XXX
if (controllerData.triggerClicks[this.hand] == 1) {
// stop highlighting, switch to grabbing
// XXX stop highlight here
// switch to grabbing
this.startNearGrabAction(controllerData, targetProps);
}
}

View file

@ -9,7 +9,8 @@
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID,
getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE,
makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS
makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS,
findGroupParent, Vec3
*/
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
@ -29,7 +30,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
this.parameters = makeDispatcherModuleParameters(
500,
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
this.hand === RIGHT_HAND ? ["rightHand", "rightHandTrigger"] : ["leftHand", "leftHandTrigger"],
[],
100);
@ -64,6 +65,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
};
this.startNearParentingGrabEntity = function (controllerData, targetProps) {
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
var handJointIndex;
@ -135,6 +137,11 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
break;
}
if (entityIsGrabbable(props)) {
// if we've attempted to grab a child, roll up to the root of the tree
var groupRootProps = findGroupParent(controllerData, props);
if (entityIsGrabbable(groupRootProps)) {
return groupRootProps;
}
return props;
}
}
@ -146,21 +153,18 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
this.grabbing = false;
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) {
makeRunningValues(false, [], []);
return makeRunningValues(false, [], []);
}
var targetProps = this.getTargetProps(controllerData);
if (targetProps) {
if (propsArePhysical(targetProps)) {
// XXX make sure no highlights are enabled from this module
return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it
} else {
this.targetEntityID = targetProps.id;
// XXX highlight this.targetEntityID here
return makeRunningValues(true, [this.targetEntityID], []);
}
} else {
// XXX make sure no highlights are enabled from this module
return makeRunningValues(false, [], []);
}
};
@ -181,8 +185,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
return readiness;
}
if (controllerData.triggerClicks[this.hand] == 1) {
// stop highlighting, switch to grabbing
// XXX stop highlight here
// switch to grab
var targetProps = this.getTargetProps(controllerData);
if (targetProps) {
this.grabbing = true;

View file

@ -0,0 +1,119 @@
"use strict";
// nearParentGrabEntity.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, getGrabbableData, Vec3,
TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS
*/
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
(function() {
function entityWantsNearTrigger(props) {
return getGrabbableData(props).triggerable;
}
function NearTriggerEntity(hand) {
this.hand = hand;
this.targetEntityID = null;
this.grabbing = false;
this.previousParentID = {};
this.previousParentJointIndex = {};
this.previouslyUnhooked = {};
this.parameters = makeDispatcherModuleParameters(
200,
this.hand === RIGHT_HAND ? ["rightHandTrigger"] : ["leftHandTrigger"],
[],
100);
this.getTargetProps = function (controllerData) {
// nearbyEntityProperties is already sorted by length from controller
var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand];
for (var i = 0; i < nearbyEntityProperties.length; i++) {
var props = nearbyEntityProperties[i];
var handPosition = controllerData.controllerLocations[this.hand].position;
var distance = Vec3.distance(props.position, handPosition);
// if (distance > NEAR_GRAB_RADIUS) {
// print("QQQ nop 0");
// break;
// }
if (entityWantsNearTrigger(props)) {
return props;
} else {
print("QQQ nop 1");
}
}
return null;
};
this.startNearTrigger = function (controllerData) {
Controller.triggerShortHapticPulse(1.0, this.hand);
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
Entities.callEntityMethod(this.targetEntityID, "startNearTrigger", args);
};
this.continueNearTrigger = function (controllerData) {
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
Entities.callEntityMethod(this.targetEntityID, "continueNearTrigger", args);
};
this.endNearTrigger = function (controllerData) {
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
Entities.callEntityMethod(this.targetEntityID, "endNearTrigger", args);
};
this.isReady = function (controllerData) {
this.targetEntityID = null;
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) {
return makeRunningValues(false, [], []);
}
var targetProps = this.getTargetProps(controllerData);
if (targetProps) {
this.targetEntityID = targetProps.id;
this.startNearTrigger(controllerData);
return makeRunningValues(true, [this.targetEntityID], []);
} else {
return makeRunningValues(false, [], []);
}
};
this.run = function (controllerData) {
if (controllerData.triggerClicks[this.hand] == 0) {
this.endNearTrigger(controllerData);
return makeRunningValues(false, [], []);
}
this.continueNearTrigger(controllerData);
return makeRunningValues(true, [this.targetEntityID], []);
};
this.cleanup = function () {
if (this.targetEntityID) {
this.endNearParentingGrabEntity();
}
};
}
var leftNearParentingGrabEntity = new NearTriggerEntity(LEFT_HAND);
var rightNearParentingGrabEntity = new NearTriggerEntity(RIGHT_HAND);
enableDispatcherModule("LeftNearParentingGrabEntity", leftNearParentingGrabEntity);
enableDispatcherModule("RightNearParentingGrabEntity", rightNearParentingGrabEntity);
this.cleanup = function () {
leftNearParentingGrabEntity.cleanup();
rightNearParentingGrabEntity.cleanup();
disableDispatcherModule("LeftNearParentingGrabEntity");
disableDispatcherModule("RightNearParentingGrabEntity");
};
Script.scriptEnding.connect(this.cleanup);
}());

View file

@ -24,7 +24,8 @@ var CONTOLLER_SCRIPTS = [
"controllerModules/nearActionGrabEntity.js",
"controllerModules/farActionGrabEntity.js",
"controllerModules/tabletStylusInput.js",
"controllerModules/equipEntity.js"
"controllerModules/equipEntity.js",
"controllerModules/nearTrigger.js"
];
var DEBUG_MENU_ITEM = "Debug defaultScripts.js";