Merge pull request #12844 from druiz17/feature-entity-highlighting

Highlight grabbable and equippable entities.
This commit is contained in:
John Conklin II 2018-04-18 15:35:46 -07:00 committed by GitHub
commit e557e0ae52
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 368 additions and 39 deletions

View file

@ -7,11 +7,12 @@
/* jslint bitwise: true */
/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation,
/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation,
controllerDispatcherPlugins:true, controllerDispatcherPluginsNeedSort:true,
LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE, DISPATCHER_PROPERTIES,
getGrabPointSphereOffset, HMD, MyAvatar, Messages, findHandChildEntities, Picks, PickType, Pointers, COLORS_GRAB_SEARCHING_HALF_SQUEEZE
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, TRIGGER_ON_VALUE, PointerManager
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, TRIGGER_ON_VALUE, PointerManager, print
Selection, DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE
*/
controllerDispatcherPlugins = {};
@ -123,6 +124,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
return getControllerWorldLocation(Controller.Standard.RightHand, true);
};
Selection.enableListHighlight(DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE);
Selection.enableListToScene(DISPATCHER_HOVERING_LIST);
this.updateTimings = function () {
_this.intervalCount++;
var thisInterval = Date.now();
@ -157,7 +161,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
this.update = function () {
try {
_this.updateInternal();
} catch (e) {
} catch (e) {
print(e);
}
Script.setTimeout(_this.update, BASIC_TIMER_INTERVAL_MS);
@ -477,6 +481,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
Controller.disableMapping(MAPPING_NAME);
_this.pointerManager.removePointers();
Pointers.removePointer(this.mouseRayPick);
Selection.disableListHighlight(DISPATCHER_HOVERING_LIST);
};
}
function mouseReleaseOnOverlay(overlayID, event) {

View file

@ -10,7 +10,7 @@
getControllerJointIndex, enableDispatcherModule, disableDispatcherModule,
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable,
cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE, Uuid
cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE, Uuid, unhighlightTargetEntity
*/
Script.include("/~/system/libraries/Xform.js");
@ -483,7 +483,13 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
this.dropGestureReset();
this.clearEquipHaptics();
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
unhighlightTargetEntity(this.targetEntityID);
var message = {
hand: this.hand,
entityID: this.targetEntityID
};
Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message));
var grabbedProperties = Entities.getEntityProperties(this.targetEntityID);
// if an object is "equipped" and has a predefined offset, use it.

View file

@ -14,7 +14,7 @@
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI
Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection
Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST
*/
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
@ -103,6 +103,7 @@ Script.include("/~/system/libraries/Xform.js");
this.contextOverlayTimer = false;
this.previousCollisionStatus = false;
this.locked = false;
this.highlightedEntity = null;
this.reticleMinX = MARGIN;
this.reticleMaxX;
this.reticleMinY = MARGIN;
@ -402,6 +403,9 @@ Script.include("/~/system/libraries/Xform.js");
if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE ||
this.notPointingAtEntity(controllerData) || this.targetIsNull()) {
this.endNearGrabAction();
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
this.highlightedEntity);
this.highlightedEntity = null;
return makeRunningValues(false, [], []);
}
this.intersectionDistance = controllerData.rayPicks[this.hand].distance;
@ -450,7 +454,9 @@ Script.include("/~/system/libraries/Xform.js");
if (rayPickInfo.type === Picks.INTERSECTED_ENTITY) {
if (controllerData.triggerClicks[this.hand]) {
var entityID = rayPickInfo.objectID;
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
this.highlightedEntity);
this.highlightedEntity = null;
var targetProps = Entities.getEntityProperties(entityID, [
"dynamic", "shapeType", "position",
"rotation", "dimensions", "density",
@ -498,38 +504,62 @@ Script.include("/~/system/libraries/Xform.js");
this.startFarGrabAction(controllerData, targetProps);
}
}
} else if (!this.entityWithContextOverlay) {
var _this = this;
} else {
var targetEntityID = rayPickInfo.objectID;
if (this.highlightedEntity !== targetEntityID) {
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
this.highlightedEntity);
var selectionTargetProps = Entities.getEntityProperties(targetEntityID, [
"dynamic", "shapeType", "position",
"rotation", "dimensions", "density",
"userData", "locked", "type", "href"
]);
if (_this.potentialEntityWithContextOverlay !== rayPickInfo.objectID) {
if (_this.contextOverlayTimer) {
Script.clearTimeout(_this.contextOverlayTimer);
var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps);
selectionTargetObject.parentProps = getEntityParents(selectionTargetProps);
var selectionTargetEntity = selectionTargetObject.getTargetEntity();
if (entityIsGrabbable(selectionTargetEntity.props) ||
entityIsGrabbable(selectionTargetObject.entityProps)) {
Selection.addToSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", rayPickInfo.objectID);
}
_this.contextOverlayTimer = false;
_this.potentialEntityWithContextOverlay = rayPickInfo.objectID;
this.highlightedEntity = rayPickInfo.objectID;
}
if (!_this.contextOverlayTimer) {
_this.contextOverlayTimer = Script.setTimeout(function () {
if (!_this.entityWithContextOverlay &&
_this.contextOverlayTimer &&
_this.potentialEntityWithContextOverlay === rayPickInfo.objectID) {
var props = Entities.getEntityProperties(rayPickInfo.objectID);
var pointerEvent = {
type: "Move",
id: _this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, rayPickInfo.intersection, props),
pos3D: rayPickInfo.intersection,
normal: rayPickInfo.surfaceNormal,
direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal),
button: "Secondary"
};
if (ContextOverlay.createOrDestroyContextOverlay(rayPickInfo.objectID, pointerEvent)) {
_this.entityWithContextOverlay = rayPickInfo.objectID;
}
if (!this.entityWithContextOverlay) {
var _this = this;
if (_this.potentialEntityWithContextOverlay !== rayPickInfo.objectID) {
if (_this.contextOverlayTimer) {
Script.clearTimeout(_this.contextOverlayTimer);
}
_this.contextOverlayTimer = false;
}, 500);
_this.potentialEntityWithContextOverlay = rayPickInfo.objectID;
}
if (!_this.contextOverlayTimer) {
_this.contextOverlayTimer = Script.setTimeout(function () {
if (!_this.entityWithContextOverlay &&
_this.contextOverlayTimer &&
_this.potentialEntityWithContextOverlay === rayPickInfo.objectID) {
var props = Entities.getEntityProperties(rayPickInfo.objectID);
var pointerEvent = {
type: "Move",
id: _this.hand + 1, // 0 is reserved for hardware mouse
pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, rayPickInfo.intersection, props),
pos3D: rayPickInfo.intersection,
normal: rayPickInfo.surfaceNormal,
direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal),
button: "Secondary"
};
if (ContextOverlay.createOrDestroyContextOverlay(rayPickInfo.objectID, pointerEvent)) {
_this.entityWithContextOverlay = rayPickInfo.objectID;
}
}
_this.contextOverlayTimer = false;
}, 500);
}
}
}
} else if (this.distanceRotating) {
@ -545,6 +575,9 @@ Script.include("/~/system/libraries/Xform.js");
if (disableModule) {
if (disableModule.disableModules) {
this.endNearGrabAction();
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
this.highlightedEntity);
this.highlightedEntity = null;
return makeRunningValues(false, [], []);
}
}

View file

@ -0,0 +1,148 @@
//
// highlightNearbyEntities.js
//
// Created by Dante Ruiz 2018-4-10
// Copyright 2017 High Fidelity, Inc.
//
// 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, Controller, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset,
makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams, entityIsCloneable, Messages, print
*/
"use strict";
(function () {
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
Script.include("/~/system/libraries/controllers.js");
Script.include("/~/system/libraries/cloneEntityUtils.js");
var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
function differenceInArrays(firstArray, secondArray) {
var differenceArray = firstArray.filter(function(element) {
return secondArray.indexOf(element) < 0;
});
return differenceArray;
}
function HighlightNearbyEntities(hand) {
this.hand = hand;
this.otherHand = hand === dispatcherUtils.RIGHT_HAND ? dispatcherUtils.LEFT_HAND :
dispatcherUtils.RIGHT_HAND;
this.highlightedEntities = [];
this.parameters = dispatcherUtils.makeDispatcherModuleParameters(
480,
this.hand === dispatcherUtils.RIGHT_HAND ? ["rightHand"] : ["leftHand"],
[],
100);
this.isGrabable = function(controllerData, props) {
var canGrabEntity = false;
if (dispatcherUtils.entityIsGrabbable(props) || entityIsCloneable(props)) {
// if we've attempted to grab a child, roll up to the root of the tree
var groupRootProps = dispatcherUtils.findGroupParent(controllerData, props);
canGrabEntity = true;
if (!dispatcherUtils.entityIsGrabbable(groupRootProps)) {
canGrabEntity = false;
}
}
return canGrabEntity;
};
this.hasHyperLink = function(props) {
return (props.href !== "" && props.href !== undefined);
};
this.removeEntityFromHighlightList = function(entityID) {
var index = this.highlightedEntities.indexOf(entityID);
if (index > -1) {
this.highlightedEntities.splice(index, 1);
}
};
this.getOtherModule = function() {
var otherModule = this.hand === dispatcherUtils.RIGHT_HAND ? leftHighlightNearbyEntities :
rightHighlightNearbyEntities;
return otherModule;
};
this.getOtherHandHighlightedEntities = function() {
return this.getOtherModule().highlightedEntities;
};
this.highlightEntities = function(controllerData) {
var nearbyEntitiesProperties = controllerData.nearbyEntityProperties[this.hand];
var otherHandHighlightedEntities = this.getOtherHandHighlightedEntities();
var newHighlightedEntities = [];
var sensorScaleFactor = MyAvatar.sensorToWorldScale;
for (var i = 0; i < nearbyEntitiesProperties.length; i++) {
var props = nearbyEntitiesProperties[i];
if (props.distance > dispatcherUtils.NEAR_GRAB_RADIUS * sensorScaleFactor) {
continue;
}
if (this.isGrabable(controllerData, props) || this.hasHyperLink(props)) {
dispatcherUtils.highlightTargetEntity(props.id);
newHighlightedEntities.push(props.id);
}
}
var unhighlightEntities = differenceInArrays(this.highlightedEntities, newHighlightedEntities);
unhighlightEntities.forEach(function(entityID) {
if (otherHandHighlightedEntities.indexOf(entityID) < 0 ) {
dispatcherUtils.unhighlightTargetEntity(entityID);
}
});
this.highlightedEntities = newHighlightedEntities;
};
this.isReady = function(controllerData) {
this.highlightEntities(controllerData);
return dispatcherUtils.makeRunningValues(false, [], []);
};
this.run = function(controllerData) {
return this.isReady(controllerData);
};
}
var handleMessage = function(channel, message, sender) {
var data;
if (sender === MyAvatar.sessionUUID) {
if (channel === 'Hifi-unhighlight-entity') {
try {
data = JSON.parse(message);
var hand = data.hand;
if (hand === dispatcherUtils.LEFT_HAND) {
leftHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID);
} else if (hand === dispatcherUtils.RIGHT_HAND) {
rightHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID);
}
} catch (e) {
print("Failed to parse message");
}
}
}
};
var leftHighlightNearbyEntities = new HighlightNearbyEntities(dispatcherUtils.LEFT_HAND);
var rightHighlightNearbyEntities = new HighlightNearbyEntities(dispatcherUtils.RIGHT_HAND);
dispatcherUtils.enableDispatcherModule("LeftHighlightNearbyEntities", leftHighlightNearbyEntities);
dispatcherUtils.enableDispatcherModule("RightHighlightNearbyEntities", rightHighlightNearbyEntities);
function cleanup() {
dispatcherUtils.disableDispatcherModule("LeftHighlightNearbyEntities");
dispatcherUtils.disableDispatcherModule("RightHighlightNearbyEntities");
}
Messages.subscribe('Hifi-unhighlight-entity');
Messages.messageReceived.connect(handleMessage);
Script.scriptEnding.connect(cleanup);
}());

View file

@ -0,0 +1,77 @@
//
// mouseHighlightEntities.js
//
// scripts/system/controllers/controllerModules/
//
// Created by Dante Ruiz 2018-4-11
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
/* jslint bitwise: true */
/* global Script, print, Entities, Picks, HMD */
(function() {
var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
function MouseHighlightEntities() {
this.highlightedEntity = null;
this.parameters = dispatcherUtils.makeDispatcherModuleParameters(
5,
["mouse"],
[],
100);
this.isReady = function(controllerData) {
if (HMD.active) {
if (this.highlightedEntity) {
dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity);
this.highlightedEntity = null;
}
} else {
var pickResult = controllerData.mouseRayPick;
if (pickResult.type === Picks.INTERSECTED_ENTITY) {
var targetEntityID = pickResult.objectID;
if (this.highlightedEntity !== targetEntityID) {
var targetProps = Entities.getEntityProperties(targetEntityID, [
"dynamic", "shapeType", "position",
"rotation", "dimensions", "density",
"userData", "locked", "type", "href"
]);
if (this.highlightedEntity) {
dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity);
this.highlightedEntity = null;
}
if (dispatcherUtils.entityIsGrabbable(targetProps)) {
// highlight entity
dispatcherUtils.highlightTargetEntity(targetEntityID);
this.highlightedEntity = targetEntityID;
}
}
}
}
return dispatcherUtils.makeRunningValues(false, [], []);
};
this.run = function(controllerData) {
return this.isReady(controllerData);
};
}
var mouseHighlightEntities = new MouseHighlightEntities();
dispatcherUtils.enableDispatcherModule("MouseHighlightEntities", mouseHighlightEntities);
function cleanup() {
dispatcherUtils.disableDispatcherModule("MouseHighlightEntities");
}
Script.scriptEnding.connect(cleanup);
})();

View file

@ -10,7 +10,7 @@
propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable,
Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues,
TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity,
HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE
HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, unhighlightTargetEntity
*/
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
@ -114,6 +114,13 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
Entities.callEntityMethod(this.targetEntityID, "startNearGrab", args);
unhighlightTargetEntity(this.targetEntityID);
var message = {
hand: this.hand,
entityID: this.targetEntityID
};
Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message));
};
// this is for when the action is going to time-out

View file

@ -11,7 +11,8 @@
TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS,
findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH,
HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME,
TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox
TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Selection, DISPATCHER_HOVERING_LIST, Uuid,
highlightTargetEntity, unhighlightTargetEntity
*/
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
@ -34,6 +35,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
this.autoUnequipCounter = 0;
this.lastUnexpectedChildrenCheckTime = 0;
this.robbed = false;
this.highlightedEntity = null;
this.parameters = makeDispatcherModuleParameters(
500,
@ -87,7 +89,13 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
this.startNearParentingGrabEntity = function (controllerData, targetProps) {
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
unhighlightTargetEntity(this.targetEntityID);
var message = {
hand: this.hand,
entityID: this.targetEntityID
};
Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message));
var handJointIndex;
// if (this.ignoreIK) {
// handJointIndex = this.controllerJointIndex;
@ -158,6 +166,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
grabbedEntity: this.targetEntityID,
joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"
}));
unhighlightTargetEntity(this.targetEntityID);
this.grabbing = false;
this.targetEntityID = null;
this.robbed = false;
@ -280,6 +289,8 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it
} else {
this.targetEntityID = targetProps.id;
this.highlightedEntity = this.targetEntityID;
highlightTargetEntity(this.targetEntityID);
return makeRunningValues(true, [this.targetEntityID], []);
}
} else {
@ -300,6 +311,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
var props = controllerData.nearbyEntityPropertiesByID[this.targetEntityID];
if (!props) {
// entity was deleted
unhighlightTargetEntity(this.targetEntityID);
this.grabbing = false;
this.targetEntityID = null;
this.hapticTargetID = null;
@ -321,6 +333,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
var readiness = this.isReady(controllerData);
if (!readiness.active) {
this.robbed = false;
unhighlightTargetEntity(this.highlightedEntity);
return readiness;
}
if (controllerData.triggerClicks[this.hand] || controllerData.secondaryValues[this.hand] > BUMPER_ON_VALUE) {

View file

@ -7,7 +7,7 @@
/* global Script, Entities, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, getGrabbableData,
Vec3, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS
Vec3, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS, unhighlightTargetEntity
*/
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
@ -55,6 +55,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
this.startNearTrigger = function (controllerData) {
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
Entities.callEntityMethod(this.targetEntityID, "startNearTrigger", args);
unhighlightTargetEntity(this.targetEntityID);
};
this.continueNearTrigger = function (controllerData) {

View file

@ -32,7 +32,9 @@ var CONTOLLER_SCRIPTS = [
"controllerModules/hudOverlayPointer.js",
"controllerModules/mouseHMD.js",
"controllerModules/scaleEntity.js",
"controllerModules/nearGrabHyperLinkEntity.js"
"controllerModules/highlightNearbyEntities.js",
"controllerModules/nearGrabHyperLinkEntity.js",
"controllerModules/mouseHighlightEntities.js"
];
var DEBUG_MENU_ITEM = "Debug defaultScripts.js";

View file

@ -15,7 +15,7 @@
//
/* global MyAvatar, Entities, Script, Camera, Vec3, Reticle, Overlays, getEntityCustomData, Messages, Quat, Controller,
isInEditMode, HMD entityIsGrabbable, Picks, PickType, Pointers*/
isInEditMode, HMD entityIsGrabbable, Picks, PickType, Pointers, unhighlightTargetEntity*/
(function() { // BEGIN LOCAL_SCOPE
@ -354,6 +354,7 @@ Grabber.prototype.pressEvent = function(event) {
Pointers.setRenderState(this.mouseRayEntities, "grabbed");
Pointers.setLockEndUUID(this.mouseRayEntities, pickResults.objectID, false);
unhighlightTargetEntity(pickResults.objectID);
mouse.startDrag(event);

View file

@ -7,6 +7,7 @@
/* global module, Camera, HMD, MyAvatar, controllerDispatcherPlugins:true, Quat, Vec3, Overlays, Xform,
Selection,
MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, FORBIDDEN_GRAB_TYPES:true,
HAPTIC_PULSE_STRENGTH:true, HAPTIC_PULSE_DURATION:true, ZERO_VEC:true, ONE_VEC:true,
DEFAULT_REGISTRATION_POINT:true, INCHES_TO_METERS:true,
@ -22,6 +23,8 @@
DISPATCHER_PROPERTIES:true,
HAPTIC_PULSE_STRENGTH:true,
HAPTIC_PULSE_DURATION:true,
DISPATCHER_HOVERING_LIST:true,
DISPATCHER_HOVERING_STYLE:true,
Entities,
makeDispatcherModuleParameters:true,
makeRunningValues:true,
@ -49,7 +52,10 @@
TEAR_AWAY_DISTANCE:true,
TEAR_AWAY_COUNT:true,
TEAR_AWAY_CHECK_TIME:true,
distanceBetweenPointAndEntityBoundingBox:true
distanceBetweenPointAndEntityBoundingBox:true,
highlightTargetEntity:true,
clearHighlightedEntities:true,
unhighlightTargetEntity:true
*/
MSECS_PER_SEC = 1000.0;
@ -88,6 +94,19 @@ NEAR_GRAB_RADIUS = 1.0;
TEAR_AWAY_DISTANCE = 0.1; // ungrab an entity if its bounding-box moves this far from the hand
TEAR_AWAY_COUNT = 2; // multiply by TEAR_AWAY_CHECK_TIME to know how long the item must be away
TEAR_AWAY_CHECK_TIME = 0.15; // seconds, duration between checks
DISPATCHER_HOVERING_LIST = "dispactherHoveringList";
DISPATCHER_HOVERING_STYLE = {
isOutlineSmooth: true,
outlineWidth: 0,
outlineUnoccludedColor: {red: 255, green: 128, blue: 128},
outlineUnoccludedAlpha: 0.0,
outlineOccludedColor: {red: 255, green: 128, blue: 128},
outlineOccludedAlpha:0.0,
fillUnoccludedColor: {red: 255, green: 255, blue: 255},
fillUnoccludedAlpha: 0.12,
fillOccludedColor: {red: 255, green: 255, blue: 255},
fillOccludedAlpha: 0.0
};
DISPATCHER_PROPERTIES = [
"position",
@ -220,6 +239,18 @@ entityIsGrabbable = function (props) {
return true;
};
clearHighlightedEntities = function() {
Selection.clearSelectedItemsList(DISPATCHER_HOVERING_LIST);
};
highlightTargetEntity = function(entityID) {
Selection.addToSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", entityID);
};
unhighlightTargetEntity = function(entityID) {
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", entityID);
};
entityIsDistanceGrabbable = function(props) {
if (!entityIsGrabbable(props)) {
return false;
@ -389,7 +420,11 @@ if (typeof module !== 'undefined') {
makeDispatcherModuleParameters: makeDispatcherModuleParameters,
enableDispatcherModule: enableDispatcherModule,
disableDispatcherModule: disableDispatcherModule,
highlightTargetEntity: highlightTargetEntity,
unhighlightTargetEntity: unhighlightTargetEntity,
clearHighlightedEntities: clearHighlightedEntities,
makeRunningValues: makeRunningValues,
findGroupParent: findGroupParent,
LEFT_HAND: LEFT_HAND,
RIGHT_HAND: RIGHT_HAND,
BUMPER_ON_VALUE: BUMPER_ON_VALUE,
@ -400,6 +435,7 @@ if (typeof module !== 'undefined') {
projectOntoOverlayXYPlane: projectOntoOverlayXYPlane,
projectOntoEntityXYPlane: projectOntoEntityXYPlane,
TRIGGER_OFF_VALUE: TRIGGER_OFF_VALUE,
TRIGGER_ON_VALUE: TRIGGER_ON_VALUE
TRIGGER_ON_VALUE: TRIGGER_ON_VALUE,
DISPATCHER_HOVERING_LIST: DISPATCHER_HOVERING_LIST
};
}