From e1299ee290fe046c0e2849e6ab513706756fa421 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 07:27:14 -0800 Subject: [PATCH 1/3] be more careful about grab action -- if it somehow expires, reinstate it --- examples/controllers/handControllerGrab.js | 102 ++++++++++++--------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index ed02bd3709..cf9b245993 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -1234,16 +1234,39 @@ function MyController(hand) { this.handleSpotlight(this.grabbedEntity); } - Entities.updateAction(this.grabbedEntity, this.actionID, { + var success = Entities.updateAction(this.grabbedEntity, this.actionID, { targetPosition: targetPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, ttl: ACTION_TTL }); + if (success) { + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + } else { + print("continueDistanceHolding -- updateAction failed"); + } + }; + + this.setupHoldAction = function() { + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: this.offsetPosition, + relativeRotation: this.offsetRotation, + ttl: ACTION_TTL, + kinematic: NEAR_GRABBING_KINEMATIC, + kinematicSetVelocity: true, + ignoreIK: this.ignoreIK + }); + if (this.actionID === NULL_ACTION_ID) { + this.actionID = null; + return false; + } + var now = Date.now(); this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); - + return true; }; this.projectVectorAlongAxis = function(position, axisStart, axisEnd) { @@ -1273,7 +1296,7 @@ function MyController(hand) { return projection - }, + }; this.nearGrabbing = function() { var now = Date.now(); @@ -1317,43 +1340,29 @@ function MyController(hand) { this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); } - this.actionID = NULL_ACTION_ID; - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: this.offsetPosition, - relativeRotation: this.offsetRotation, - ttl: ACTION_TTL, - kinematic: NEAR_GRABBING_KINEMATIC, - kinematicSetVelocity: true, - ignoreIK: this.ignoreIK - }); - if (this.actionID === NULL_ACTION_ID) { - this.actionID = null; - } else { - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); - if (this.state == STATE_NEAR_GRABBING) { - this.setState(STATE_CONTINUE_NEAR_GRABBING); - } else { - // equipping - Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); - this.startHandGrasp(); - - this.setState(STATE_CONTINUE_EQUIP_BD); - } - - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - - Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); - - Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); - + if (!this.setupHoldAction()) { + return; } + if (this.state == STATE_NEAR_GRABBING) { + this.setState(STATE_CONTINUE_NEAR_GRABBING); + } else { + // equipping + Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]); + this.startHandGrasp(); + + this.setState(STATE_CONTINUE_EQUIP_BD); + } + + if (this.hand === RIGHT_HAND) { + Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); + } else { + Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); + } + + Entities.callEntityMethod(this.grabbedEntity, "setHand", [this.hand]); + Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); + this.currentHandControllerTipPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition; @@ -1403,7 +1412,7 @@ function MyController(hand) { if (this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) { // if less than a 5 seconds left, refresh the actions ttl - Entities.updateAction(this.grabbedEntity, this.actionID, { + var success = Entities.updateAction(this.grabbedEntity, this.actionID, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, @@ -1413,7 +1422,13 @@ function MyController(hand) { kinematicSetVelocity: true, ignoreIK: this.ignoreIK }); - this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + if (success) { + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); + } else { + print("continueNearGrabbing -- updateAction failed"); + Entities.deleteAction(this.grabbedEntity, this.actionID); + this.setupHoldAction(); + } } }; @@ -1460,7 +1475,7 @@ function MyController(hand) { return; } } else { - Entities.updateAction(this.grabbedEntity, this.equipSpringID, { + var success = Entities.updateAction(this.grabbedEntity, this.equipSpringID, { targetPosition: targetPosition, linearTimeScale: EQUIP_SPRING_TIMEFRAME, targetRotation: targetRotation, @@ -1468,6 +1483,9 @@ function MyController(hand) { ttl: ACTION_TTL, ignoreIK: ignoreIK }); + if (!success) { + print("pullTowardEquipPosition -- updateActionfailed"); + } } if (Vec3.distance(grabbedProperties.position, targetPosition) < EQUIP_SPRING_SHUTOFF_DISTANCE) { @@ -1849,4 +1867,4 @@ function cleanup() { } Script.scriptEnding.connect(cleanup); -Script.update.connect(update); \ No newline at end of file +Script.update.connect(update); From 5d0604b8d31f1f8c81e7e3a911f86d2bbc07e79f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 07:33:10 -0800 Subject: [PATCH 2/3] activateBody doesn't help if called from inside the action callback, because the callback isn't called on inactive bodies. call it from the setup routine, instead --- interface/src/avatar/AvatarActionHold.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 689d557c48..4dda14e194 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -89,6 +89,8 @@ void AvatarActionHold::prepareForPhysicsSimulation() { // code here for future reference. // _palmRotationFromRigidBody = avatarRotationInverse * palmRotation; }); + + activateBody(); } std::shared_ptr AvatarActionHold::getTarget(glm::quat& rotation, glm::vec3& position) { @@ -197,7 +199,6 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { if (_kinematic) { doKinematicUpdate(deltaTimeStep); } else { - activateBody(); forceBodyNonStatic(); ObjectActionSpring::updateActionWorker(deltaTimeStep); } @@ -247,7 +248,6 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { _previousSet = true; }); - activateBody(); forceBodyNonStatic(); } @@ -344,7 +344,6 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { ownerEntity->setActionDataNeedsTransmit(true); } }); - activateBody(); } return true; @@ -431,6 +430,5 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) { _active = true; }); - activateBody(); forceBodyNonStatic(); } From 2c210928089b4b8753272655b6a5392e76ef315b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 3 Jan 2016 07:59:49 -0800 Subject: [PATCH 3/3] be more careful about locking --- libraries/physics/src/ObjectAction.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 17b565ba21..e8e1188dc9 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -23,15 +23,15 @@ ObjectAction::~ObjectAction() { } void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) { - bool ownerEntityExpired = false; quint64 expiresWhen = 0; + EntityItemPointer ownerEntity = nullptr; withReadLock([&]{ - ownerEntityExpired = _ownerEntity.expired(); + ownerEntity = _ownerEntity.lock(); expiresWhen = _expires; }); - if (ownerEntityExpired) { + if (!ownerEntity) { qDebug() << "warning -- action with no entity removing self from btCollisionWorld."; btDynamicsWorld* dynamicsWorld = static_cast(collisionWorld); if (dynamicsWorld) { @@ -43,10 +43,8 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta if (expiresWhen > 0) { quint64 now = usecTimestampNow(); if (now > expiresWhen) { - EntityItemPointer ownerEntity = nullptr; QUuid myID; withWriteLock([&]{ - ownerEntity = _ownerEntity.lock(); _active = false; myID = getID(); });