split the grab script's deactivation on an entity into two parts -- one that happens during release and a delayed part which finishes up. This makes collisions with a thrower's capsule less likely

This commit is contained in:
Seth Alves 2016-07-12 11:42:58 -07:00
parent 1abd49c167
commit 1999193907

View file

@ -181,9 +181,9 @@ var COLLIDES_WITH_WHILE_MULTI_GRABBED = "dynamic";
var HEART_BEAT_INTERVAL = 5 * MSECS_PER_SEC; var HEART_BEAT_INTERVAL = 5 * MSECS_PER_SEC;
var HEART_BEAT_TIMEOUT = 15 * MSECS_PER_SEC; var HEART_BEAT_TIMEOUT = 15 * MSECS_PER_SEC;
var avCollideLater; var delayedDeactivateFunc;
var setCollidesLaterTimeout; var delayedDeactivateTimeout;
var collideLaterID; var delayedDeactivateEntityID;
var CONTROLLER_STATE_MACHINE = {}; var CONTROLLER_STATE_MACHINE = {};
@ -2064,15 +2064,15 @@ function MyController(hand) {
} }
this.entityActivated = true; this.entityActivated = true;
if (setCollidesLaterTimeout && collideLaterID == entityID) { if (delayedDeactivateTimeout && delayedDeactivateEntityID == entityID) {
// we have a timeout waiting to set collisions with myAvatar back on (so that when something // we have a timeout waiting to set collisions with myAvatar back on (so that when something
// is thrown it doesn't collide with the avatar's capsule the moment it's released). We've // is thrown it doesn't collide with the avatar's capsule the moment it's released). We've
// regrabbed the entity before the timeout fired, so cancel the timeout, run the function now // regrabbed the entity before the timeout fired, so cancel the timeout, run the function now
// and adjust the grabbedProperties. This will make the saved set of properties (the ones that // and adjust the grabbedProperties. This will make the saved set of properties (the ones that
// get re-instated after all the grabs have been released) be correct. // get re-instated after all the grabs have been released) be correct.
Script.clearTimeout(setCollidesLaterTimeout); Script.clearTimeout(delayedDeactivateTimeout);
setCollidesLaterTimeout = null; delayedDeactivateTimeout = null;
grabbedProperties["collidesWith"] = avCollideLater(); grabbedProperties["collidesWith"] = delayedDeactivateFunc();
} }
var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {}); var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {});
@ -2142,7 +2142,27 @@ function MyController(hand) {
}); });
}; };
this.deactivateEntity = function (entityID, noVelocity) { this.delayedDeactivateEntity = function (entityID, collidesWith) {
// If, before the grab started, the held entity collided with myAvatar, we do the deactivation in
// two parts. Most of it is done in deactivateEntity(), but the final collidesWith and refcount
// are delayed a bit. This keeps thrown things from colliding with the avatar's capsule so often.
// The refcount is handled in this delayed fashion so things don't get confused if someone else
// grabs the entity before the timeout fires.
Entities.editEntity(entityID, { collidesWith: collidesWith });
var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {});
if (data && data["refCount"]) {
data["refCount"] = data["refCount"] - 1;
if (data["refCount"] < 1) {
data = null;
}
} else {
data = null;
}
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
};
this.deactivateEntity = function (entityID, noVelocity, delayed) {
var deactiveProps; var deactiveProps;
if (!this.entityActivated) { if (!this.entityActivated) {
@ -2151,12 +2171,13 @@ function MyController(hand) {
this.entityActivated = false; this.entityActivated = false;
var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {}); var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {});
var doDelayedDeactivate = false;
if (data && data["refCount"]) { if (data && data["refCount"]) {
data["refCount"] = data["refCount"] - 1; data["refCount"] = data["refCount"] - 1;
if (data["refCount"] < 1) { if (data["refCount"] < 1) {
deactiveProps = { deactiveProps = {
gravity: data["gravity"], gravity: data["gravity"],
// don't set collidesWith back right away, because thrown things tend to bounce off the // don't set collidesWith myAvatar back right away, because thrown things tend to bounce off the
// avatar's capsule. // avatar's capsule.
collidesWith: removeMyAvatarFromCollidesWith(data["collidesWith"]), collidesWith: removeMyAvatarFromCollidesWith(data["collidesWith"]),
collisionless: data["collisionless"], collisionless: data["collisionless"],
@ -2165,17 +2186,20 @@ function MyController(hand) {
parentJointIndex: data["parentJointIndex"] parentJointIndex: data["parentJointIndex"]
}; };
if (data["collidesWith"].indexOf("myAvatar") >= 0) { doDelayedDeactivate = (data["collidesWith"].indexOf("myAvatar") >= 0);
var javaScriptScopingIsBrokenData = data;
avCollideLater = function () { if (doDelayedDeactivate) {
var delayedCollidesWith = data["collidesWith"];
var delayedEntityID = entityID;
delayedDeactivateFunc = function () {
// set collidesWith back to original value a bit later than the rest // set collidesWith back to original value a bit later than the rest
_this.setCollidesLaterTimeout = null; delayedDeactivateTimeout = null;
Entities.editEntity(entityID, { collidesWith: javaScriptScopingIsBrokenData["collidesWith"] }); _this.delayedDeactivateEntity(delayedEntityID, delayedCollidesWith);
return javaScriptScopingIsBrokenData["collidesWith"]; return delayedCollidesWith;
} }
setCollidesLaterTimeout = delayedDeactivateTimeout =
Script.setTimeout(avCollideLater, COLLIDE_WITH_AV_AFTER_RELEASE_DELAY * MSECS_PER_SEC); Script.setTimeout(delayedDeactivateFunc, COLLIDE_WITH_AV_AFTER_RELEASE_DELAY * MSECS_PER_SEC);
collideLaterID = entityID; delayedDeactivateEntityID = entityID;
} }
// things that are held by parenting and dropped with no velocity will end up as "static" in bullet. If // things that are held by parenting and dropped with no velocity will end up as "static" in bullet. If
@ -2220,7 +2244,6 @@ function MyController(hand) {
// angularVelocity: this.currentAngularVelocity // angularVelocity: this.currentAngularVelocity
}); });
} }
data = null; data = null;
} else if (this.shouldResetParentOnRelease) { } else if (this.shouldResetParentOnRelease) {
// we parent-grabbed this from another parent grab. try to put it back where we found it. // we parent-grabbed this from another parent grab. try to put it back where we found it.
@ -2239,7 +2262,9 @@ function MyController(hand) {
} else { } else {
data = null; data = null;
} }
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); if (!doDelayedDeactivate) {
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
}
}; };
this.getOtherHandController = function () { this.getOtherHandController = function () {