Merge pull request #14814 from sethalves/fix-edit-in-releaseGrab

case 20919: Fix edit in release grab
This commit is contained in:
John Conklin II 2019-02-05 14:48:59 -08:00 committed by GitHub
commit ec0bdba7fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 72 additions and 17 deletions

View file

@ -5300,6 +5300,21 @@ void MyAvatar::releaseGrab(const QUuid& grabID) {
bool tellHandler { false };
_avatarGrabsLock.withWriteLock([&] {
std::map<QUuid, GrabPointer>::iterator itr;
itr = _avatarGrabs.find(grabID);
if (itr != _avatarGrabs.end()) {
GrabPointer grab = itr->second;
if (grab) {
grab->setReleased(true);
bool success;
SpatiallyNestablePointer target = SpatiallyNestable::findByID(grab->getTargetID(), success);
if (target && success) {
target->disableGrab(grab);
}
}
}
if (_avatarGrabData.remove(grabID)) {
_grabsToDelete.push_back(grabID);
tellHandler = true;

View file

@ -412,6 +412,9 @@ void Avatar::accumulateGrabPositions(std::map<QUuid, GrabLocationAccumulator>& g
if (!grab || !grab->getActionID().isNull()) {
continue; // the accumulated value isn't used, in this case.
}
if (grab->getReleased()) {
continue;
}
glm::vec3 jointTranslation = getAbsoluteJointTranslationInObjectFrame(grab->getParentJointIndex());
glm::quat jointRotation = getAbsoluteJointRotationInObjectFrame(grab->getParentJointIndex());

View file

@ -59,6 +59,7 @@ public:
virtual bool isReadyForAdd() const { return true; }
bool isActive() { return _active; }
void deactivate() { _active = false; }
virtual void removeFromSimulation(EntitySimulationPointer simulation) const = 0;
virtual EntityItemWeakPointer getOwnerEntity() const = 0;

View file

@ -3506,3 +3506,13 @@ void EntityItem::removeGrab(GrabPointer grab) {
}
disableNoBootstrap();
}
void EntityItem::disableGrab(GrabPointer grab) {
QUuid actionID = grab->getActionID();
if (!actionID.isNull()) {
EntityDynamicPointer action = _grabActions.value(actionID);
if (action) {
action->deactivate();
}
}
}

View file

@ -561,6 +561,7 @@ public:
virtual void addGrab(GrabPointer grab) override;
virtual void removeGrab(GrabPointer grab) override;
virtual void disableGrab(GrabPointer grab) override;
signals:
void requestRenderUpdate();

View file

@ -115,17 +115,30 @@ void EntityMotionState::updateServerPhysicsVariables() {
}
void EntityMotionState::handleDeactivation() {
// copy _server data to entity
Transform localTransform = _entity->getLocalTransform();
localTransform.setTranslation(_serverPosition);
localTransform.setRotation(_serverRotation);
_entity->setLocalTransformAndVelocities(localTransform, ENTITY_ITEM_ZERO_VEC3, ENTITY_ITEM_ZERO_VEC3);
// and also to RigidBody
btTransform worldTrans;
worldTrans.setOrigin(glmToBullet(_entity->getWorldPosition()));
worldTrans.setRotation(glmToBullet(_entity->getWorldOrientation()));
_body->setWorldTransform(worldTrans);
// no need to update velocities... should already be zero
if (_entity->getDirtyFlags() & (Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES)) {
// Some non-physical event (script-call or network-packet) has modified the entity's transform and/or velocities
// at the last minute before deactivation --> the values stored in _server* and _body are stale.
// We assume the EntityMotionState is the last to know, so we copy from EntityItem and let things sort themselves out.
Transform localTransform;
_entity->getLocalTransformAndVelocities(localTransform, _serverVelocity, _serverAngularVelocity);
_serverPosition = localTransform.getTranslation();
_serverRotation = localTransform.getRotation();
_serverAcceleration = _entity->getAcceleration();
_serverActionData = _entity->getDynamicData();
_lastStep = ObjectMotionState::getWorldSimulationStep();
} else {
// copy _server data to entity
Transform localTransform = _entity->getLocalTransform();
localTransform.setTranslation(_serverPosition);
localTransform.setRotation(_serverRotation);
_entity->setLocalTransformAndVelocities(localTransform, ENTITY_ITEM_ZERO_VEC3, ENTITY_ITEM_ZERO_VEC3);
// and also to RigidBody
btTransform worldTrans;
worldTrans.setOrigin(glmToBullet(_entity->getWorldPosition()));
worldTrans.setRotation(glmToBullet(_entity->getWorldOrientation()));
_body->setWorldTransform(worldTrans);
// no need to update velocities... should already be zero
}
}
// virtual

View file

@ -26,16 +26,16 @@ public:
void accumulate(glm::vec3 position, glm::quat orientation) {
_position += position;
_orientation = orientation; // XXX
count++;
_count++;
}
glm::vec3 finalizePosition() { return count > 0 ? _position * (1.0f / count) : glm::vec3(0.0f); }
glm::vec3 finalizePosition() { return _count > 0 ? _position * (1.0f / _count) : glm::vec3(0.0f); }
glm::quat finalizeOrientation() { return _orientation; } // XXX
protected:
glm::vec3 _position;
glm::quat _orientation;
int count { 0 };
int _count { 0 };
};
class Grab {
@ -48,7 +48,8 @@ public:
_parentJointIndex(newParentJointIndex),
_hand(newHand),
_positionalOffset(newPositionalOffset),
_rotationalOffset(newRotationalOffset) {}
_rotationalOffset(newRotationalOffset),
_released(false) {}
QByteArray toByteArray();
bool fromByteArray(const QByteArray& grabData);
@ -61,6 +62,7 @@ public:
_positionalOffset = other->_positionalOffset;
_rotationalOffset = other->_rotationalOffset;
_actionID = other->_actionID;
_released = other->_released;
return *this;
}
@ -85,6 +87,9 @@ public:
glm::quat getRotationalOffset() const { return _rotationalOffset; }
void setRotationalOffset(glm::quat rotationalOffset) { _rotationalOffset = rotationalOffset; }
bool getReleased() const { return _released; }
void setReleased(bool value) { _released = value; }
protected:
QUuid _actionID; // if an action is created in bullet for this grab, this is the ID
QUuid _ownerID; // avatar ID of grabber
@ -93,6 +98,7 @@ protected:
QString _hand; // "left" or "right"
glm::vec3 _positionalOffset; // relative to joint
glm::quat _rotationalOffset; // relative to joint
bool _released { false }; // released and scheduled for deletion
};

View file

@ -1390,7 +1390,12 @@ void SpatiallyNestable::removeGrab(GrabPointer grab) {
bool SpatiallyNestable::hasGrabs() {
bool result { false };
_grabsLock.withReadLock([&] {
result = !_grabs.isEmpty();
foreach (const GrabPointer &grab, _grabs) {
if (grab && !grab->getReleased()) {
result = true;
break;
}
}
});
return result;
}

View file

@ -218,6 +218,7 @@ public:
virtual void addGrab(GrabPointer grab);
virtual void removeGrab(GrabPointer grab);
virtual void disableGrab(GrabPointer grab) {};
bool hasGrabs();
virtual QUuid getEditSenderID();
@ -241,7 +242,7 @@ protected:
quint64 _rotationChanged { 0 };
mutable ReadWriteLockable _grabsLock;
QSet<GrabPointer> _grabs;
QSet<GrabPointer> _grabs; // upon this thing
private:
SpatiallyNestable() = delete;