Merge pull request #10210 from volansystech/21200

21200 Transfer from far-grab to near grab when close
This commit is contained in:
Seth Alves 2017-04-27 10:32:10 -07:00 committed by GitHub
commit 0435749f82

View file

@ -111,12 +111,12 @@ var EQUIP_RADIUS = 0.2; // radius used for palm vs equip-hotspot for equipping.
// has reached the required position, and then grow larger once the hand is close enough to equip.
var EQUIP_HOTSPOT_RENDER_RADIUS = 0.0; // radius used for palm vs equip-hotspot for rendering hot-spots
var MAX_EQUIP_HOTSPOT_RADIUS = 1.0;
var MAX_FAR_TO_NEAR_EQUIP_HOTSPOT_RADIUS = 0.5; // radius used for far to near equipping object.
var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position
var NEAR_GRAB_RADIUS = 0.1; // radius used for palm vs object for near grabbing.
var NEAR_GRAB_MAX_DISTANCE = 1.0; // you cannot grab objects that are this far away from your hand
var FAR_TO_NEAR_GRAB_MAX_DISTANCE = 0.3; // In far to near grabbing conversion,grab the object if distancetoObject from hand is less than this.
var NEAR_GRAB_PICK_RADIUS = 0.25; // radius used for search ray vs object for near grabbing.
var NEAR_GRABBING_KINEMATIC = true; // force objects to be kinematic when near-grabbed
@ -155,6 +155,7 @@ var INCHES_TO_METERS = 1.0 / 39.3701;
// these control how long an abandoned pointer line or action will hang around
var ACTION_TTL = 15; // seconds
var ACTION_TTL_ZERO = 0; // seconds
var ACTION_TTL_REFRESH = 5;
var PICKS_PER_SECOND_PER_HAND = 60;
var MSECS_PER_SEC = 1000.0;
@ -192,6 +193,7 @@ var FORBIDDEN_GRAB_TYPES = ["Unknown", "Light", "PolyLine", "Zone"];
var holdEnabled = true;
var nearGrabEnabled = true;
var farGrabEnabled = true;
var farToNearGrab = false;
var myAvatarScalingEnabled = true;
var objectScalingEnabled = true;
var mostRecentSearchingHand = RIGHT_HAND;
@ -2097,6 +2099,15 @@ function MyController(hand) {
return true;
};
this.entityIsFarToNearGrabbable = function (objectPosition, handPosition, maxDistance) {
var distanceToObjectFromHand = Vec3.length(Vec3.subtract(handPosition, objectPosition));
if (distanceToObjectFromHand > maxDistance) {
return false;
}
return true;
};
this.chooseNearEquipHotspots = function(candidateEntities, distance) {
var equippableHotspots = flatten(candidateEntities.map(function(entityID) {
return _this.collectEquipHotspots(entityID);
@ -2125,6 +2136,34 @@ function MyController(hand) {
return null;
}
};
this.chooseNearEquipHotspotsForFarToNearEquip = function(candidateEntities, distance) {
var equippableHotspots = flatten(candidateEntities.map(function(entityID) {
return _this.collectEquipHotspots(entityID);
})).filter(function(hotspot) {
return (Vec3.distance(hotspot.worldPosition, getControllerWorldLocation(_this.handToController(), true).position) <
hotspot.radius + distance);
});
return equippableHotspots;
};
this.chooseBestEquipHotspotForFarToNearEquip = function(candidateEntities) {
var DISTANCE = 1;
var equippableHotspots = this.chooseNearEquipHotspotsForFarToNearEquip(candidateEntities, DISTANCE);
var _this = this;
if (equippableHotspots.length > 0) {
// sort by distance
equippableHotspots.sort(function(a, b) {
var handControllerLocation = getControllerWorldLocation(_this.handToController(), true);
var aDistance = Vec3.distance(a.worldPosition, handControllerLocation.position);
var bDistance = Vec3.distance(b.worldPosition, handControllerLocation.position);
return aDistance - bDistance;
});
return equippableHotspots[0];
} else {
return null;
}
};
this.searchEnter = function() {
mostRecentSearchingHand = this.hand;
@ -2680,6 +2719,55 @@ function MyController(hand) {
this.grabbedThingID);
var distanceToObject = Vec3.length(Vec3.subtract(MyAvatar.position, this.currentObjectPosition));
var candidateHotSpotEntities = Entities.findEntities(controllerLocation.position,MAX_FAR_TO_NEAR_EQUIP_HOTSPOT_RADIUS);
entityPropertiesCache.addEntities(candidateHotSpotEntities);
var potentialEquipHotspot = this.chooseBestEquipHotspotForFarToNearEquip(candidateHotSpotEntities);
if (potentialEquipHotspot && (potentialEquipHotspot.entityID == this.grabbedThingID)) {
if ((this.triggerSmoothedGrab() || this.secondarySqueezed()) && holdEnabled) {
this.grabbedHotspot = potentialEquipHotspot;
this.grabbedThingID = potentialEquipHotspot.entityID;
this.grabbedIsOverlay = false;
var success = Entities.updateAction(this.grabbedThingID, this.actionID, {
targetPosition: newTargetPosition,
linearTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
targetRotation: this.currentObjectRotation,
angularTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
ttl: ACTION_TTL_ZERO
});
if (success) {
this.actionTimeout = now + (ACTION_TTL_ZERO * MSECS_PER_SEC);
} else {
print("continueDistanceHolding -- updateAction failed");
}
this.setState(STATE_HOLD, "equipping '" + entityPropertiesCache.getProps(this.grabbedThingID).name + "'");
return;
}
}
var rayPositionOnEntity = Vec3.subtract(grabbedProperties.position, this.offsetPosition);
//Far to Near Grab: If object is draw by user inside FAR_TO_NEAR_GRAB_MAX_DISTANCE, grab it
if (this.entityIsFarToNearGrabbable(rayPositionOnEntity, controllerLocation.position, FAR_TO_NEAR_GRAB_MAX_DISTANCE)) {
this.farToNearGrab = true;
var success = Entities.updateAction(this.grabbedThingID, this.actionID, {
targetPosition: newTargetPosition,
linearTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
targetRotation: this.currentObjectRotation,
angularTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
ttl: ACTION_TTL_ZERO // Overriding ACTION_TTL,Assign ACTION_TTL_ZERO so that the object is dropped down immediately after the trigger is released.
});
if (success) {
this.actionTimeout = now + (ACTION_TTL_ZERO * MSECS_PER_SEC);
} else {
print("continueDistanceHolding -- updateAction failed");
}
this.setState(STATE_NEAR_GRABBING , "near grab entity '" + this.grabbedThingID + "'");
return;
}
this.linearTimeScale = (this.linearTimeScale / 2);
if (this.linearTimeScale <= DISTANCE_HOLDING_ACTION_TIMEFRAME) {
this.linearTimeScale = DISTANCE_HOLDING_ACTION_TIMEFRAME;
@ -3058,6 +3146,15 @@ function MyController(hand) {
this.nearGrabbing = function(deltaTime, timestamp) {
this.grabPointSphereOff();
var ttl = ACTION_TTL;
if (this.farToNearGrab) {
ttl = ACTION_TTL_ZERO; // farToNearGrab - Assign ACTION_TTL_ZERO so that, the object is dropped down immediately after the trigger is released.
if(!this.triggerClicked){
this.farToNearGrab = false;
}
}
if (this.state == STATE_NEAR_GRABBING && (!this.triggerClicked && this.secondaryReleased())) {
this.callEntityMethodOnGrabbed("releaseGrab");
this.setState(STATE_OFF, "trigger released");
@ -3225,20 +3322,20 @@ function MyController(hand) {
this.maybeScale(props);
}
if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSECS_PER_SEC) {
if (this.actionID && this.actionTimeout - now < ttl * MSECS_PER_SEC) {
// if less than a 5 seconds left, refresh the actions ttl
var success = Entities.updateAction(this.grabbedThingID, this.actionID, {
hand: this.hand === RIGHT_HAND ? "right" : "left",
timeScale: NEAR_GRABBING_ACTION_TIMEFRAME,
relativePosition: this.offsetPosition,
relativeRotation: this.offsetRotation,
ttl: ACTION_TTL,
ttl: ttl,
kinematic: this.kinematicGrab,
kinematicSetVelocity: true,
ignoreIK: this.ignoreIK
});
if (success) {
this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC);
this.actionTimeout = now + (ttl * MSECS_PER_SEC);
} else {
print("continueNearGrabbing -- updateAction failed");
Entities.deleteAction(this.grabbedThingID, this.actionID);