mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 08:49:05 +02:00
adding entity selection for far grabbing
This commit is contained in:
parent
a1ce9481bb
commit
c9c3d8f332
3 changed files with 78 additions and 32 deletions
|
@ -7,11 +7,12 @@
|
||||||
|
|
||||||
/* jslint bitwise: true */
|
/* jslint bitwise: true */
|
||||||
|
|
||||||
/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation,
|
/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation,
|
||||||
controllerDispatcherPlugins:true, controllerDispatcherPluginsNeedSort:true,
|
controllerDispatcherPlugins:true, controllerDispatcherPluginsNeedSort:true,
|
||||||
LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE, DISPATCHER_PROPERTIES,
|
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
|
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 = {};
|
controllerDispatcherPlugins = {};
|
||||||
|
@ -123,6 +124,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
return getControllerWorldLocation(Controller.Standard.RightHand, true);
|
return getControllerWorldLocation(Controller.Standard.RightHand, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Selection.enableListHighlight(DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE);
|
||||||
|
|
||||||
this.updateTimings = function () {
|
this.updateTimings = function () {
|
||||||
_this.intervalCount++;
|
_this.intervalCount++;
|
||||||
var thisInterval = Date.now();
|
var thisInterval = Date.now();
|
||||||
|
@ -157,7 +160,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
this.update = function () {
|
this.update = function () {
|
||||||
try {
|
try {
|
||||||
_this.updateInternal();
|
_this.updateInternal();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
}
|
}
|
||||||
Script.setTimeout(_this.update, BASIC_TIMER_INTERVAL_MS);
|
Script.setTimeout(_this.update, BASIC_TIMER_INTERVAL_MS);
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
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,
|
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||||
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI
|
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");
|
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||||
|
@ -103,6 +103,7 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
this.contextOverlayTimer = false;
|
this.contextOverlayTimer = false;
|
||||||
this.previousCollisionStatus = false;
|
this.previousCollisionStatus = false;
|
||||||
this.locked = false;
|
this.locked = false;
|
||||||
|
this.highlightedEntity = null;
|
||||||
this.reticleMinX = MARGIN;
|
this.reticleMinX = MARGIN;
|
||||||
this.reticleMaxX;
|
this.reticleMaxX;
|
||||||
this.reticleMinY = MARGIN;
|
this.reticleMinY = MARGIN;
|
||||||
|
@ -449,7 +450,9 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
if (rayPickInfo.type === Picks.INTERSECTED_ENTITY) {
|
if (rayPickInfo.type === Picks.INTERSECTED_ENTITY) {
|
||||||
if (controllerData.triggerClicks[this.hand]) {
|
if (controllerData.triggerClicks[this.hand]) {
|
||||||
var entityID = rayPickInfo.objectID;
|
var entityID = rayPickInfo.objectID;
|
||||||
|
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
||||||
|
this.highlightedEntity);
|
||||||
|
this.highlightedEntity = null;
|
||||||
var targetProps = Entities.getEntityProperties(entityID, [
|
var targetProps = Entities.getEntityProperties(entityID, [
|
||||||
"dynamic", "shapeType", "position",
|
"dynamic", "shapeType", "position",
|
||||||
"rotation", "dimensions", "density",
|
"rotation", "dimensions", "density",
|
||||||
|
@ -497,38 +500,62 @@ Script.include("/~/system/libraries/Xform.js");
|
||||||
this.startFarGrabAction(controllerData, targetProps);
|
this.startFarGrabAction(controllerData, targetProps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!this.entityWithContextOverlay) {
|
} else {
|
||||||
var _this = this;
|
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) {
|
var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps);
|
||||||
if (_this.contextOverlayTimer) {
|
selectionTargetObject.parentProps = getEntityParents(selectionTargetProps);
|
||||||
Script.clearTimeout(_this.contextOverlayTimer);
|
var selectionTargetEntity = selectionTargetObject.getTargetEntity();
|
||||||
|
|
||||||
|
if (entityIsGrabbable(selectionTargetEntity.props) ||
|
||||||
|
entityIsGrabbable(selectionTargetObject.entityProps)) {
|
||||||
|
|
||||||
|
Selection.addToSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", rayPickInfo.objectID);
|
||||||
}
|
}
|
||||||
_this.contextOverlayTimer = false;
|
this.highlightedEntity = rayPickInfo.objectID;
|
||||||
_this.potentialEntityWithContextOverlay = rayPickInfo.objectID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_this.contextOverlayTimer) {
|
if (!this.entityWithContextOverlay) {
|
||||||
_this.contextOverlayTimer = Script.setTimeout(function () {
|
var _this = this;
|
||||||
if (!_this.entityWithContextOverlay &&
|
|
||||||
_this.contextOverlayTimer &&
|
if (_this.potentialEntityWithContextOverlay !== rayPickInfo.objectID) {
|
||||||
_this.potentialEntityWithContextOverlay === rayPickInfo.objectID) {
|
if (_this.contextOverlayTimer) {
|
||||||
var props = Entities.getEntityProperties(rayPickInfo.objectID);
|
Script.clearTimeout(_this.contextOverlayTimer);
|
||||||
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;
|
_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) {
|
} else if (this.distanceRotating) {
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
DISPATCHER_PROPERTIES:true,
|
DISPATCHER_PROPERTIES:true,
|
||||||
HAPTIC_PULSE_STRENGTH:true,
|
HAPTIC_PULSE_STRENGTH:true,
|
||||||
HAPTIC_PULSE_DURATION:true,
|
HAPTIC_PULSE_DURATION:true,
|
||||||
|
DISPATCHER_HOVERING_LIST:true,
|
||||||
|
DISPATCHER_HOVERING_STYLE:true,
|
||||||
Entities,
|
Entities,
|
||||||
makeDispatcherModuleParameters:true,
|
makeDispatcherModuleParameters:true,
|
||||||
makeRunningValues:true,
|
makeRunningValues:true,
|
||||||
|
@ -88,6 +90,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_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_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
|
TEAR_AWAY_CHECK_TIME = 0.15; // seconds, duration between checks
|
||||||
|
DISPATCHER_HOVERING_LIST = "dispactherHoveringList";
|
||||||
|
DISPATCHER_HOVERING_STYLE = {
|
||||||
|
isOutlineSmooth: true,
|
||||||
|
outlineWidth: 5,
|
||||||
|
outlineUnoccludedColor: {red: 255, green: 128, blue: 128},
|
||||||
|
outlineUnoccludedAlpha: 0.88,
|
||||||
|
outlineOccludedColor: {red: 255, green: 128, blue: 128},
|
||||||
|
outlineOccludedAlpha:0.5,
|
||||||
|
fillUnoccludedColor: {red: 26, green: 0, blue: 0},
|
||||||
|
fillUnoccludedAlpha: 0.0,
|
||||||
|
fillOccludedColor: {red: 26, green: 0, blue: 0},
|
||||||
|
fillOccludedAlpha: 0.0
|
||||||
|
};
|
||||||
|
|
||||||
DISPATCHER_PROPERTIES = [
|
DISPATCHER_PROPERTIES = [
|
||||||
"position",
|
"position",
|
||||||
|
@ -400,6 +415,7 @@ if (typeof module !== 'undefined') {
|
||||||
projectOntoOverlayXYPlane: projectOntoOverlayXYPlane,
|
projectOntoOverlayXYPlane: projectOntoOverlayXYPlane,
|
||||||
projectOntoEntityXYPlane: projectOntoEntityXYPlane,
|
projectOntoEntityXYPlane: projectOntoEntityXYPlane,
|
||||||
TRIGGER_OFF_VALUE: TRIGGER_OFF_VALUE,
|
TRIGGER_OFF_VALUE: TRIGGER_OFF_VALUE,
|
||||||
TRIGGER_ON_VALUE: TRIGGER_ON_VALUE
|
TRIGGER_ON_VALUE: TRIGGER_ON_VALUE,
|
||||||
|
DISPATCHER_HOVERING_LIST: DISPATCHER_HOVERING_LIST
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue