This commit is contained in:
Seth Alves 2017-07-27 18:22:17 -07:00
parent fcf1dc839a
commit cfe3981bc2
3 changed files with 84 additions and 82 deletions

View File

@ -5,21 +5,20 @@
// 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, controllerDispatcherPlugins, Controller, Vec3, getControllerWorldLocation */
/* global Script, Entities, controllerDispatcherPlugins, Controller, Vec3, getControllerWorldLocation,
LEFT_HAND, RIGHT_HAND */
controllerDispatcherPlugins = {};
Script.include("/~/system/libraries/utils.js");
Script.include("/~/system/libraries/controllers.js");
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
(function() {
var _this = this;
var LEFT_HAND = 0;
var RIGHT_HAND = 1;
var NEAR_GRAB_RADIUS = 0.1;
var NEAR_GRAB_MAX_DISTANCE = 1.0; // you cannot grab objects that are this far away from your hand
var NEAR_MIN_RADIUS = 0.1;
var NEAR_MAX_RADIUS = 1.0;
var DISPATCHER_PROPERTIES = [
@ -72,13 +71,13 @@ Script.include("/~/system/libraries/controllers.js");
for (var i = LEFT_HAND; i <= RIGHT_HAND; i ++) {
// todo: check controllerLocations[i].valid
var controllerPosition = controllerLocations[i].position;
var nearbyEntityIDs = Entities.findEntities(controllerPosition, NEAR_GRAB_RADIUS);
var nearbyEntityIDs = Entities.findEntities(controllerPosition, NEAR_MIN_RADIUS);
for (var j = 0; j < nearbyEntityIDs.length; j++) {
var entityID = nearbyEntityIDs[j];
var props = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES);
props.id = entityID;
props.distanceFromController = Vec3.length(Vec3.subtract(controllerPosition, props.position));
if (props.distanceFromController < NEAR_GRAB_MAX_DISTANCE) {
if (props.distanceFromController < NEAR_MAX_RADIUS) {
nearbyEntityProperties[i].push(props);
}
}

View File

@ -0,0 +1,54 @@
"use strict";
// controllerDispatcherUtils.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 Camera, HMD, MyAvatar, getControllerJointIndex,
LEFT_HAND, RIGHT_HAND, NULL_UUID, AVATAR_SELF_ID, getGrabbableData */
LEFT_HAND = 0;
RIGHT_HAND = 1;
NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
getGrabbableData = function (props) {
// look in userData for a "grabbable" key, return the value or some defaults
var grabbableData = {};
var userDataParsed = null;
try {
userDataParsed = JSON.parse(props.userData);
} catch (err) {
}
if (userDataParsed && userDataParsed.grabbable) {
grabbableData = userDataParsed.grabbable;
}
if (!grabbableData.hasOwnProperty("grabbable")) {
grabbableData.grabbable = true;
}
return grabbableData;
};
getControllerJointIndex = function (hand) {
if (HMD.isHandControllerAvailable()) {
var controllerJointIndex = -1;
if (Camera.mode === "first person") {
controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ?
"_CONTROLLER_RIGHTHAND" :
"_CONTROLLER_LEFTHAND");
} else if (Camera.mode === "third person") {
controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ?
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
}
return controllerJointIndex;
}
return MyAvatar.getJointIndex("Head");
};

View File

@ -6,82 +6,31 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global Script, Entities, HMD, Camera, MyAvatar, Controller, controllerDispatcherPlugins */
/* global Script, Entities, MyAvatar, Controller, controllerDispatcherPlugins,
RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, getGrabbableData, NULL_UUID */
Script.include("/~/system/controllers/controllerDispatcherUtils.js");
(function() {
var LEFT_HAND = 0;
var RIGHT_HAND = 1;
var HAPTIC_PULSE_STRENGTH = 1.0;
var HAPTIC_PULSE_DURATION = 13.0;
var FORBIDDEN_GRAB_TYPES = ["Unknown", "Light", "PolyLine", "Zone"];
var FORBIDDEN_GRAB_NAMES = ["Grab Debug Entity", "grab pointer"];
var NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
var AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
function getControllerJointIndex(hand) {
if (HMD.isHandControllerAvailable()) {
var controllerJointIndex = -1;
if (Camera.mode === "first person") {
controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ?
"_CONTROLLER_RIGHTHAND" :
"_CONTROLLER_LEFTHAND");
} else if (Camera.mode === "third person") {
controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ?
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
}
return controllerJointIndex;
}
return MyAvatar.getJointIndex("Head");
}
function propsArePhysical(props) {
if (!props.dynamic) {
return false;
}
var isPhysical = (props.shapeType && props.shapeType != 'none');
return isPhysical;
}
function entityIsGrabbable(props) {
var grabbableProps = {};
var userDataParsed = null;
try {
userDataParsed = JSON.parse(props.userData);
} catch (err) {
}
if (userDataParsed && userDataParsed.grabbable) {
grabbableProps = userDataParsed.grabbable;
}
var grabbable = propsArePhysical(props);
if (grabbableProps.hasOwnProperty("grabbable")) {
grabbable = grabbableProps.grabbable;
}
if (!grabbable) {
return false;
}
if (FORBIDDEN_GRAB_TYPES.indexOf(props.type) >= 0) {
return false;
}
if (props.locked) {
return false;
}
if (FORBIDDEN_GRAB_NAMES.indexOf(props.name) >= 0) {
function entityIsParentingGrabbable(props) {
var grabbable = getGrabbableData(props).grabbable;
if (!grabbable ||
props.locked ||
FORBIDDEN_GRAB_TYPES.indexOf(props.type) >= 0 ||
FORBIDDEN_GRAB_NAMES.indexOf(props.name) >= 0) {
return false;
}
return true;
}
function NearGrab(hand) {
function NearGrabParenting(hand) {
this.priority = 5;
this.hand = hand;
@ -119,7 +68,7 @@
return false;
};
this.startNearGrab = function (controllerData, grabbedProperties) {
this.startNearGrabParenting = function (controllerData, grabbedProperties) {
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
var reparentProps = {
@ -140,7 +89,7 @@
Entities.editEntity(this.grabbedThingID, reparentProps);
};
this.endNearGrab = function (controllerData) {
this.endNearGrabParenting = function (controllerData) {
if (this.previousParentID[this.grabbedThingID] === NULL_UUID) {
Entities.editEntity(this.grabbedThingID, {
parentID: this.previousParentID[this.grabbedThingID],
@ -169,7 +118,7 @@
for (var i = 0; i < nearbyEntityProperties.length; i ++) {
var props = nearbyEntityProperties[i];
if (entityIsGrabbable(props)) {
if (entityIsParentingGrabbable(props)) {
if (props.distanceFromController < bestDistance) {
bestDistance = props.distanceFromController;
grabbedProperties = props;
@ -179,7 +128,7 @@
if (grabbedProperties) {
this.grabbedThingID = grabbedProperties.id;
this.startNearGrab(controllerData, grabbedProperties);
this.startNearGrabParenting(controllerData, grabbedProperties);
return true;
} else {
return false;
@ -188,29 +137,29 @@
this.run = function (controllerData) {
if (controllerData.triggerClicks[this.hand] == 0) {
this.endNearGrab(controllerData);
this.endNearGrabParenting(controllerData);
return false;
}
return true;
};
}
var leftNearGrab = new NearGrab(LEFT_HAND);
leftNearGrab.name = "leftNearGrab";
var leftNearGrabParenting = new NearGrabParenting(LEFT_HAND);
leftNearGrabParenting.name = "leftNearGrabParenting";
var rightNearGrab = new NearGrab(RIGHT_HAND);
rightNearGrab.name = "rightNearGrab";
var rightNearGrabParenting = new NearGrabParenting(RIGHT_HAND);
rightNearGrabParenting.name = "rightNearGrabParenting";
if (!controllerDispatcherPlugins) {
controllerDispatcherPlugins = {};
}
controllerDispatcherPlugins.leftNearGrab = leftNearGrab;
controllerDispatcherPlugins.rightNearGrab = rightNearGrab;
controllerDispatcherPlugins.leftNearGrabParenting = leftNearGrabParenting;
controllerDispatcherPlugins.rightNearGrabParenting = rightNearGrabParenting;
this.cleanup = function () {
delete controllerDispatcherPlugins.leftNearGrab;
delete controllerDispatcherPlugins.rightNearGrab;
delete controllerDispatcherPlugins.leftNearGrabParenting;
delete controllerDispatcherPlugins.rightNearGrabParenting;
};
Script.scriptEnding.connect(this.cleanup);
}());