mirror of
https://github.com/overte-org/overte.git
synced 2025-08-05 11:19:51 +02:00
grabbing overlays works, again
This commit is contained in:
parent
7ae41064db
commit
9fb1835a26
3 changed files with 195 additions and 5 deletions
|
@ -5,7 +5,7 @@
|
||||||
// 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 Script, Entities, controllerDispatcherPlugins, Controller, Vec3, getControllerWorldLocation,
|
/* global Script, Entities, Overlays, controllerDispatcherPlugins, Controller, Vec3, getControllerWorldLocation,
|
||||||
LEFT_HAND, RIGHT_HAND */
|
LEFT_HAND, RIGHT_HAND */
|
||||||
|
|
||||||
controllerDispatcherPlugins = {};
|
controllerDispatcherPlugins = {};
|
||||||
|
@ -48,7 +48,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
var highVarianceCount = 0;
|
var highVarianceCount = 0;
|
||||||
var veryhighVarianceCount = 0;
|
var veryhighVarianceCount = 0;
|
||||||
|
|
||||||
// a module can occupy one or more slots while it's running. If all the required slots for a module are
|
// a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are
|
||||||
// not set to false (not in use), a module cannot start. When a module is using a slot, that module's name
|
// not set to false (not in use), a module cannot start. When a module is using a slot, that module's name
|
||||||
// is stored as the value, rather than false.
|
// is stored as the value, rather than false.
|
||||||
this.activitySlots = {
|
this.activitySlots = {
|
||||||
|
@ -56,7 +56,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
rightHand: false
|
rightHand: false
|
||||||
};
|
};
|
||||||
|
|
||||||
this.slotsAreAvailable = function (plugin) {
|
this.slotsAreAvailableForPlugin = function (plugin) {
|
||||||
for (var i = 0; i < plugin.parameters.activitySlots.length; i++) {
|
for (var i = 0; i < plugin.parameters.activitySlots.length; i++) {
|
||||||
if (_this.activitySlots[plugin.parameters.activitySlots[i]]) {
|
if (_this.activitySlots[plugin.parameters.activitySlots[i]]) {
|
||||||
return false; // something is already using a slot which _this plugin requires
|
return false; // something is already using a slot which _this plugin requires
|
||||||
|
@ -140,8 +140,28 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
var controllerLocations = [_this.dataGatherers.leftControllerLocation(),
|
var controllerLocations = [_this.dataGatherers.leftControllerLocation(),
|
||||||
_this.dataGatherers.rightControllerLocation()];
|
_this.dataGatherers.rightControllerLocation()];
|
||||||
|
|
||||||
|
// find 3d overlays near each hand
|
||||||
|
var nearbyOverlayIDs = [];
|
||||||
|
var h;
|
||||||
|
for (h = LEFT_HAND; h <= RIGHT_HAND; h++) {
|
||||||
|
// todo: check controllerLocations[h].valid
|
||||||
|
var nearbyOverlays = Overlays.findOverlays(controllerLocations[h].position, NEAR_MIN_RADIUS);
|
||||||
|
var makeOverlaySorter = function (handIndex) {
|
||||||
|
return function (a, b) {
|
||||||
|
var aPosition = Overlays.getProperty(a, "position");
|
||||||
|
var aDistance = Vec3.distance(aPosition, controllerLocations[handIndex]);
|
||||||
|
var bPosition = Overlays.getProperty(b, "position");
|
||||||
|
var bDistance = Vec3.distance(bPosition, controllerLocations[handIndex]);
|
||||||
|
return aDistance - bDistance;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
nearbyOverlays.sort(makeOverlaySorter(h));
|
||||||
|
nearbyOverlayIDs.push(nearbyOverlays);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find entities near each hand
|
||||||
var nearbyEntityProperties = [[], []];
|
var nearbyEntityProperties = [[], []];
|
||||||
for (var h = LEFT_HAND; h <= RIGHT_HAND; h++) {
|
for (h = LEFT_HAND; h <= RIGHT_HAND; h++) {
|
||||||
// todo: check controllerLocations[h].valid
|
// todo: check controllerLocations[h].valid
|
||||||
var controllerPosition = controllerLocations[h].position;
|
var controllerPosition = controllerLocations[h].position;
|
||||||
var nearbyEntityIDs = Entities.findEntities(controllerPosition, NEAR_MIN_RADIUS);
|
var nearbyEntityIDs = Entities.findEntities(controllerPosition, NEAR_MIN_RADIUS);
|
||||||
|
@ -165,11 +185,13 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
nearbyEntityProperties[h].sort(makeSorter(h));
|
nearbyEntityProperties[h].sort(makeSorter(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bundle up all the data about the current situation
|
||||||
var controllerData = {
|
var controllerData = {
|
||||||
triggerValues: [_this.leftTriggerValue, _this.rightTriggerValue],
|
triggerValues: [_this.leftTriggerValue, _this.rightTriggerValue],
|
||||||
triggerClicks: [_this.leftTriggerClicked, _this.rightTriggerClicked],
|
triggerClicks: [_this.leftTriggerClicked, _this.rightTriggerClicked],
|
||||||
controllerLocations: controllerLocations,
|
controllerLocations: controllerLocations,
|
||||||
nearbyEntityProperties: nearbyEntityProperties,
|
nearbyEntityProperties: nearbyEntityProperties,
|
||||||
|
nearbyOverlayIDs: nearbyOverlayIDs
|
||||||
};
|
};
|
||||||
|
|
||||||
// print("QQQ dispatcher " + JSON.stringify(_this.runningPluginNames) + " : " + JSON.stringify(_this.activitySlots));
|
// print("QQQ dispatcher " + JSON.stringify(_this.runningPluginNames) + " : " + JSON.stringify(_this.activitySlots));
|
||||||
|
@ -179,7 +201,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
// TODO sort names by plugin.priority
|
// TODO sort names by plugin.priority
|
||||||
if (controllerDispatcherPlugins.hasOwnProperty(pluginName)) {
|
if (controllerDispatcherPlugins.hasOwnProperty(pluginName)) {
|
||||||
var candidatePlugin = controllerDispatcherPlugins[pluginName];
|
var candidatePlugin = controllerDispatcherPlugins[pluginName];
|
||||||
if (_this.slotsAreAvailable(candidatePlugin) && candidatePlugin.isReady(controllerData, deltaTime)) {
|
if (_this.slotsAreAvailableForPlugin(candidatePlugin) && candidatePlugin.isReady(controllerData, deltaTime)) {
|
||||||
// this plugin will start. add it to the list of running plugins and mark the
|
// this plugin will start. add it to the list of running plugins and mark the
|
||||||
// activity-slots which this plugin consumes as "in use"
|
// activity-slots which this plugin consumes as "in use"
|
||||||
_this.runningPluginNames[pluginName] = true;
|
_this.runningPluginNames[pluginName] = true;
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// nearParentGrabOverlay.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, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID,
|
||||||
|
getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
|
||||||
|
Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||||
|
makeDispatcherModuleParameters, Overlays
|
||||||
|
*/
|
||||||
|
|
||||||
|
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
// XXX this.ignoreIK = (grabbableData.ignoreIK !== undefined) ? grabbableData.ignoreIK : true;
|
||||||
|
// XXX this.kinematicGrab = (grabbableData.kinematic !== undefined) ? grabbableData.kinematic : NEAR_GRABBING_KINEMATIC;
|
||||||
|
|
||||||
|
function NearParentingGrabOverlay(hand) {
|
||||||
|
this.hand = hand;
|
||||||
|
this.grabbedThingID = null;
|
||||||
|
this.previousParentID = {};
|
||||||
|
this.previousParentJointIndex = {};
|
||||||
|
this.previouslyUnhooked = {};
|
||||||
|
|
||||||
|
this.parameters = makeDispatcherModuleParameters(
|
||||||
|
500,
|
||||||
|
this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
|
||||||
|
[],
|
||||||
|
100);
|
||||||
|
|
||||||
|
|
||||||
|
// XXX does handJointIndex change if the avatar changes?
|
||||||
|
this.handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||||
|
this.controllerJointIndex = getControllerJointIndex(this.hand);
|
||||||
|
|
||||||
|
this.thisHandIsParent = function(props) {
|
||||||
|
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== AVATAR_SELF_ID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||||
|
if (props.parentJointIndex == handJointIndex) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var controllerJointIndex = this.controllerJointIndex;
|
||||||
|
if (props.parentJointIndex == controllerJointIndex) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var controllerCRJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ?
|
||||||
|
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
||||||
|
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
|
||||||
|
if (props.parentJointIndex == controllerCRJointIndex) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.startNearParentingGrabOverlay = function (controllerData) {
|
||||||
|
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
||||||
|
|
||||||
|
var handJointIndex;
|
||||||
|
// if (this.ignoreIK) {
|
||||||
|
// handJointIndex = this.controllerJointIndex;
|
||||||
|
// } else {
|
||||||
|
// handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||||
|
// }
|
||||||
|
handJointIndex = this.controllerJointIndex;
|
||||||
|
|
||||||
|
var grabbedProperties = {
|
||||||
|
position: Overlays.getProperty(this.grabbedThingID, "position"),
|
||||||
|
rotation: Overlays.getProperty(this.grabbedThingID, "rotation"),
|
||||||
|
parentID: Overlays.getProperty(this.grabbedThingID, "parentID"),
|
||||||
|
parentJointIndex: Overlays.getProperty(this.grabbedThingID, "parentJointIndex"),
|
||||||
|
dynamic: false,
|
||||||
|
shapeType: "none"
|
||||||
|
};
|
||||||
|
|
||||||
|
var reparentProps = {
|
||||||
|
parentID: AVATAR_SELF_ID,
|
||||||
|
parentJointIndex: handJointIndex,
|
||||||
|
velocity: {x: 0, y: 0, z: 0},
|
||||||
|
angularVelocity: {x: 0, y: 0, z: 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.thisHandIsParent(grabbedProperties)) {
|
||||||
|
// this should never happen, but if it does, don't set previous parent to be this hand.
|
||||||
|
// this.previousParentID[this.grabbedThingID] = NULL;
|
||||||
|
// this.previousParentJointIndex[this.grabbedThingID] = -1;
|
||||||
|
} else {
|
||||||
|
this.previousParentID[this.grabbedThingID] = grabbedProperties.parentID;
|
||||||
|
this.previousParentJointIndex[this.grabbedThingID] = grabbedProperties.parentJointIndex;
|
||||||
|
}
|
||||||
|
Overlays.editOverlay(this.grabbedThingID, reparentProps);
|
||||||
|
|
||||||
|
Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({
|
||||||
|
action: 'grab',
|
||||||
|
grabbedEntity: this.grabbedThingID,
|
||||||
|
joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.endNearParentingGrabOverlay = function (controllerData) {
|
||||||
|
if (this.previousParentID[this.grabbedThingID] === NULL_UUID) {
|
||||||
|
Overlays.editOverlay(this.grabbedThingID, {
|
||||||
|
parentID: NULL_UUID,
|
||||||
|
parentJointIndex: -1
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// before we grabbed it, overlay was a child of something; put it back.
|
||||||
|
Overlays.editOverlay(this.grabbedThingID, {
|
||||||
|
parentID: this.previousParentID[this.grabbedThingID],
|
||||||
|
parentJointIndex: this.previousParentJointIndex[this.grabbedThingID],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.grabbedThingID = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isReady = function (controllerData) {
|
||||||
|
if (controllerData.triggerClicks[this.hand] == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.grabbedThingID = null;
|
||||||
|
|
||||||
|
var candidateOverlays = controllerData.nearbyOverlayIDs[this.hand];
|
||||||
|
print("candidateOverlays.length = " + candidateOverlays.length);
|
||||||
|
var grabbableOverlays = candidateOverlays.filter(function(overlayID) {
|
||||||
|
return Overlays.getProperty(overlayID, "grabbable");
|
||||||
|
});
|
||||||
|
print("grabbableOverlays.length = " + grabbableOverlays.length);
|
||||||
|
|
||||||
|
if (grabbableOverlays.length > 0) {
|
||||||
|
this.grabbedThingID = grabbableOverlays[0];
|
||||||
|
this.startNearParentingGrabOverlay(controllerData);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.run = function (controllerData) {
|
||||||
|
if (controllerData.triggerClicks[this.hand] == 0) {
|
||||||
|
this.endNearParentingGrabOverlay(controllerData);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
enableDispatcherModule("LeftNearParentingGrabOverlay", new NearParentingGrabOverlay(LEFT_HAND));
|
||||||
|
enableDispatcherModule("RightNearParentingGrabOverlay", new NearParentingGrabOverlay(RIGHT_HAND));
|
||||||
|
|
||||||
|
this.cleanup = function () {
|
||||||
|
disableDispatcherModule("LeftNearParentingGrabOverlay");
|
||||||
|
disableDispatcherModule("RightNearParentingGrabOverlay");
|
||||||
|
};
|
||||||
|
Script.scriptEnding.connect(this.cleanup);
|
||||||
|
}());
|
|
@ -20,6 +20,7 @@ var CONTOLLER_SCRIPTS = [
|
||||||
|
|
||||||
"ControllerDispatcher.js",
|
"ControllerDispatcher.js",
|
||||||
"controllerModules/nearParentGrabEntity.js",
|
"controllerModules/nearParentGrabEntity.js",
|
||||||
|
"controllerModules/nearParentGrabOverlay.js",
|
||||||
"controllerModules/nearActionGrabEntity.js",
|
"controllerModules/nearActionGrabEntity.js",
|
||||||
"controllerModules/tabletStylusInput.js"
|
"controllerModules/tabletStylusInput.js"
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue