From 7c528497402133e049e16d3ffbd7294f6a5e8b9d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 11:36:58 -0700 Subject: [PATCH 01/33] change how hold action works --- interface/src/avatar/Avatar.cpp | 62 +++++++++ interface/src/avatar/Avatar.h | 10 ++ interface/src/avatar/AvatarActionHold.cpp | 156 ++++++++++++++-------- interface/src/avatar/AvatarActionHold.h | 3 +- interface/src/avatar/AvatarManager.cpp | 8 ++ interface/src/avatar/AvatarManager.h | 3 +- interface/src/avatar/MyAvatar.cpp | 64 --------- interface/src/avatar/MyAvatar.h | 9 -- 8 files changed, 188 insertions(+), 127 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index c0636314b5..7796e4d840 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -56,6 +56,7 @@ const float DISPLAYNAME_FADE_TIME = 0.5f; const float DISPLAYNAME_FADE_FACTOR = pow(0.01f, 1.0f / DISPLAYNAME_FADE_TIME); const float DISPLAYNAME_ALPHA = 1.0f; const float DISPLAYNAME_BACKGROUND_ALPHA = 0.4f; +const glm::vec3 HAND_TO_PALM_OFFSET(0.0f, 0.12f, 0.08f); namespace render { template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar) { @@ -1167,3 +1168,64 @@ void Avatar::rebuildSkeletonBody() { DependencyManager::get()->updateAvatarPhysicsShape(getSessionUUID()); } +glm::vec3 Avatar::getLeftPalmPosition() { + glm::vec3 leftHandPosition; + getSkeletonModel().getLeftHandPosition(leftHandPosition); + glm::quat leftRotation; + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation); + leftHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftRotation); + return leftHandPosition; +} + +glm::vec3 Avatar::getLeftPalmVelocity() { + const PalmData* palm = getHand()->getPalm(LEFT_HAND_INDEX); + if (palm != NULL) { + return palm->getVelocity(); + } + return glm::vec3(0.0f); +} + +glm::vec3 Avatar::getLeftPalmAngularVelocity() { + const PalmData* palm = getHand()->getPalm(LEFT_HAND_INDEX); + if (palm != NULL) { + return palm->getRawAngularVelocity(); + } + return glm::vec3(0.0f); +} + +glm::quat Avatar::getLeftPalmRotation() { + glm::quat leftRotation; + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation); + return leftRotation; +} + +glm::vec3 Avatar::getRightPalmPosition() { + glm::vec3 rightHandPosition; + getSkeletonModel().getRightHandPosition(rightHandPosition); + glm::quat rightRotation; + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation); + rightHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightRotation); + return rightHandPosition; +} + +glm::vec3 Avatar::getRightPalmVelocity() { + const PalmData* palm = getHand()->getPalm(RIGHT_HAND_INDEX); + if (palm != NULL) { + return palm->getVelocity(); + } + return glm::vec3(0.0f); +} + +glm::vec3 Avatar::getRightPalmAngularVelocity() { + const PalmData* palm = getHand()->getPalm(RIGHT_HAND_INDEX); + if (palm != NULL) { + return palm->getRawAngularVelocity(); + } + return glm::vec3(0.0f); +} + +glm::quat Avatar::getRightPalmRotation() { + glm::quat rightRotation; + getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation); + return rightRotation; +} diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 534aefd3cb..9a46a145c2 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -174,6 +174,16 @@ public: void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; } AvatarMotionState* getMotionState() { return _motionState; } +public slots: + glm::vec3 getLeftPalmPosition(); + glm::vec3 getLeftPalmVelocity(); + glm::vec3 getLeftPalmAngularVelocity(); + glm::quat getLeftPalmRotation(); + glm::vec3 getRightPalmPosition(); + glm::vec3 getRightPalmVelocity(); + glm::vec3 getRightPalmAngularVelocity(); + glm::quat getRightPalmRotation(); + protected: SkeletonModel _skeletonModel; glm::vec3 _skeletonOffset; diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 1fa50b79fd..ced5c83b08 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -22,7 +22,7 @@ AvatarActionHold::AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntit _relativePosition(glm::vec3(0.0f)), _relativeRotation(glm::quat()), _hand("right"), - _mine(false) + _holderID(QUuid()) { _type = ACTION_TYPE_HOLD; #if WANT_DEBUG @@ -37,48 +37,46 @@ AvatarActionHold::~AvatarActionHold() { } void AvatarActionHold::updateActionWorker(float deltaTimeStep) { - if (!_mine) { - // if a local script isn't updating this, then we are just getting spring-action data over the wire. - // let the super-class handle it. - ObjectActionSpring::updateActionWorker(deltaTimeStep); - return; - } + QSharedPointer avatarManager = DependencyManager::get(); + AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID); + std::shared_ptr holdingAvatar = std::static_pointer_cast(holdingAvatarData); - glm::quat rotation; - glm::vec3 position; - glm::vec3 offset; - bool gotLock = withTryReadLock([&]{ - auto myAvatar = DependencyManager::get()->getMyAvatar(); - glm::vec3 palmPosition; - glm::quat palmRotation; - if (_hand == "right") { - palmPosition = myAvatar->getRightPalmPosition(); - palmRotation = myAvatar->getRightPalmRotation(); - } else { - palmPosition = myAvatar->getLeftPalmPosition(); - palmRotation = myAvatar->getLeftPalmRotation(); + if (holdingAvatar) { + glm::quat rotation; + glm::vec3 position; + glm::vec3 offset; + bool gotLock = withTryReadLock([&]{ + glm::vec3 palmPosition; + glm::quat palmRotation; + if (_hand == "right") { + palmPosition = holdingAvatar->getRightPalmPosition(); + palmRotation = holdingAvatar->getRightPalmRotation(); + } else { + palmPosition = holdingAvatar->getLeftPalmPosition(); + palmRotation = holdingAvatar->getLeftPalmRotation(); + } + + rotation = palmRotation * _relativeRotation; + offset = rotation * _relativePosition; + position = palmPosition + offset; + }); + + if (gotLock) { + gotLock = withTryWriteLock([&]{ + if (_positionalTarget != position || _rotationalTarget != rotation) { + auto ownerEntity = _ownerEntity.lock(); + if (ownerEntity) { + ownerEntity->setActionDataDirty(true); + } + _positionalTarget = position; + _rotationalTarget = rotation; + } + }); } - rotation = palmRotation * _relativeRotation; - offset = rotation * _relativePosition; - position = palmPosition + offset; - }); - - if (gotLock) { - gotLock = withTryWriteLock([&]{ - if (_positionalTarget != position || _rotationalTarget != rotation) { - auto ownerEntity = _ownerEntity.lock(); - if (ownerEntity) { - ownerEntity->setActionDataDirty(true); - } - _positionalTarget = position; - _rotationalTarget = rotation; - } - }); - } - - if (gotLock) { - ObjectActionSpring::updateActionWorker(deltaTimeStep); + if (gotLock) { + ObjectActionSpring::updateActionWorker(deltaTimeStep); + } } } @@ -100,7 +98,7 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { if (!ok) { relativeRotation = _relativeRotation; } - + ok = true; float timeScale = EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false); @@ -115,35 +113,46 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { hand = _hand; } + ok = true; + auto myAvatar = DependencyManager::get()->getMyAvatar(); + auto holderID = myAvatar->getSessionUUID(); + QString holderIDString = + EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); + if (ok) { + holderID = QUuid(holderIDString); + } + if (relativePosition != _relativePosition || relativeRotation != _relativeRotation || timeScale != _linearTimeScale - || hand != _hand) { + || hand != _hand + || holderID != _holderID) { withWriteLock([&] { _relativePosition = relativePosition; _relativeRotation = relativeRotation; const float MIN_TIMESCALE = 0.1f; - _linearTimeScale = glm::min(MIN_TIMESCALE, timeScale); + _linearTimeScale = glm::max(MIN_TIMESCALE, timeScale); _angularTimeScale = _linearTimeScale; _hand = hand; + _holderID = holderID; - _mine = true; _active = true; activateBody(); + + auto ownerEntity = _ownerEntity.lock(); + if (ownerEntity) { + ownerEntity->setActionDataDirty(true); + } }); } + return true; } - QVariantMap AvatarActionHold::getArguments() { QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&]{ - if (!_mine) { - arguments = ObjectActionSpring::getArguments(); - return; - } - + arguments["holderID"] = _holderID; arguments["relativePosition"] = glmToQMap(_relativePosition); arguments["relativeRotation"] = glmToQMap(_relativeRotation); arguments["timeScale"] = _linearTimeScale; @@ -152,9 +161,52 @@ QVariantMap AvatarActionHold::getArguments() { return arguments; } +QByteArray AvatarActionHold::serialize() const { + QByteArray serializedActionArguments; + QDataStream dataStream(&serializedActionArguments, QIODevice::WriteOnly); + + dataStream << ACTION_TYPE_SPRING; + dataStream << getID(); + dataStream << AvatarActionHold::holdVersion; + + dataStream << _holderID; + dataStream << _relativePosition; + dataStream << _relativeRotation; + dataStream << _linearTimeScale; + dataStream << _hand; + + dataStream << _expires; + dataStream << _tag; + + return serializedActionArguments; +} void AvatarActionHold::deserialize(QByteArray serializedArguments) { - if (!_mine) { - ObjectActionSpring::deserialize(serializedArguments); + QDataStream dataStream(serializedArguments); + + EntityActionType type; + dataStream >> type; + assert(type == getType()); + + QUuid id; + dataStream >> id; + assert(id == getID()); + + uint16_t serializationVersion; + dataStream >> serializationVersion; + if (serializationVersion != AvatarActionHold::holdVersion) { + return; } + + dataStream >> _holderID; + dataStream >> _relativePosition; + dataStream >> _relativeRotation; + dataStream >> _linearTimeScale; + _angularTimeScale = _linearTimeScale; + dataStream >> _hand; + + dataStream >> _expires; + dataStream >> _tag; + + _active = true; } diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index 3500b5dfa1..613d2ef3a3 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -27,6 +27,7 @@ public: virtual void updateActionWorker(float deltaTimeStep); + QByteArray serialize() const; virtual void deserialize(QByteArray serializedArguments); private: @@ -35,7 +36,7 @@ private: glm::vec3 _relativePosition; glm::quat _relativeRotation; QString _hand; - bool _mine = false; + QUuid _holderID; }; #endif // hifi_AvatarActionHold_h diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 69d76db7de..6e52fa1f85 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -343,3 +343,11 @@ void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { } } } + + +AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& sessionID) { + if (sessionID == _myAvatar->getSessionUUID()) { + return std::static_pointer_cast(_myAvatar); + } + return getAvatarHash()[sessionID]; +} diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 277e931419..35c18dff0b 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -35,7 +35,8 @@ public: void init(); MyAvatar* getMyAvatar() { return _myAvatar.get(); } - + AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID); + void updateMyAvatar(float deltaTime); void updateOtherAvatars(float deltaTime); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 605a81e9d9..58d677aeec 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -493,70 +493,6 @@ void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } } -const glm::vec3 HAND_TO_PALM_OFFSET(0.0f, 0.12f, 0.08f); - -glm::vec3 MyAvatar::getLeftPalmPosition() { - glm::vec3 leftHandPosition; - getSkeletonModel().getLeftHandPosition(leftHandPosition); - glm::quat leftRotation; - getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation); - leftHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftRotation); - return leftHandPosition; -} - -glm::vec3 MyAvatar::getLeftPalmVelocity() { - const PalmData* palm = getHand()->getPalm(LEFT_HAND_INDEX); - if (palm != NULL) { - return palm->getVelocity(); - } - return glm::vec3(0.0f); -} - -glm::vec3 MyAvatar::getLeftPalmAngularVelocity() { - const PalmData* palm = getHand()->getPalm(LEFT_HAND_INDEX); - if (palm != NULL) { - return palm->getRawAngularVelocity(); - } - return glm::vec3(0.0f); -} - -glm::quat MyAvatar::getLeftPalmRotation() { - glm::quat leftRotation; - getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation); - return leftRotation; -} - -glm::vec3 MyAvatar::getRightPalmPosition() { - glm::vec3 rightHandPosition; - getSkeletonModel().getRightHandPosition(rightHandPosition); - glm::quat rightRotation; - getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation); - rightHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightRotation); - return rightHandPosition; -} - -glm::vec3 MyAvatar::getRightPalmVelocity() { - const PalmData* palm = getHand()->getPalm(RIGHT_HAND_INDEX); - if (palm != NULL) { - return palm->getVelocity(); - } - return glm::vec3(0.0f); -} - -glm::vec3 MyAvatar::getRightPalmAngularVelocity() { - const PalmData* palm = getHand()->getPalm(RIGHT_HAND_INDEX); - if (palm != NULL) { - return palm->getRawAngularVelocity(); - } - return glm::vec3(0.0f); -} - -glm::quat MyAvatar::getRightPalmRotation() { - glm::quat rightRotation; - getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation); - return rightRotation; -} - void MyAvatar::clearReferential() { changeReferential(NULL); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index cca0c4152f..60962ff1a6 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -199,15 +199,6 @@ public slots: Q_INVOKABLE void updateMotionBehaviorFromMenu(); - glm::vec3 getLeftPalmPosition(); - glm::vec3 getLeftPalmVelocity(); - glm::vec3 getLeftPalmAngularVelocity(); - glm::quat getLeftPalmRotation(); - glm::vec3 getRightPalmPosition(); - glm::vec3 getRightPalmVelocity(); - glm::vec3 getRightPalmAngularVelocity(); - glm::quat getRightPalmRotation(); - void clearReferential(); bool setModelReferential(const QUuid& id); bool setJointReferential(const QUuid& id, int jointIndex); From 83780296de1b2139aa4b07ce902112319bed1644 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 12:12:57 -0700 Subject: [PATCH 02/33] don't send physical property updates if there's an action on the object --- libraries/entities/src/EntityItem.cpp | 8 ++++++++ libraries/entities/src/EntityItem.h | 1 + libraries/physics/src/EntityMotionState.cpp | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index a8f3adc12e..ad1708c7e7 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1788,3 +1788,11 @@ QVariantMap EntityItem::getActionArguments(const QUuid& actionID) const { return result; } + +bool EntityItem::shouldSuppressEdits() const { + QHash::const_iterator i = _objectActions.begin(); + while (i != _objectActions.end()) { + // XXX + return true; + } +} diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index cddd9df312..59651bfaf0 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -424,6 +424,7 @@ public: QVariantMap getActionArguments(const QUuid& actionID) const; void deserializeActions(); void setActionDataDirty(bool value) const { _actionDataDirty = value; } + bool shouldSuppressEdits() const; protected: diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 42bf9bd438..5cfdd4125f 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -291,6 +291,10 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { return true; } + if (_entity->shouldSuppressEdits()) { + return false; + } + // Else we measure the error between current and extrapolated transform (according to expected behavior // of remote EntitySimulation) and return true if the error is significant. From 54eac099b971fc738a99858c5ca1f1d4125748c3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 12:52:53 -0700 Subject: [PATCH 03/33] tweak --- libraries/entities/src/EntityItem.cpp | 2 ++ libraries/physics/src/EntityMotionState.cpp | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index ad1708c7e7..cb141c930d 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1795,4 +1795,6 @@ bool EntityItem::shouldSuppressEdits() const { // XXX return true; } + + return false; } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 5cfdd4125f..6be9938aff 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -280,6 +280,11 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { } _lastStep = simulationStep; + + if (_entity->shouldSuppressEdits()) { + return false; + } + if (glm::length2(_serverVelocity) > 0.0f) { _serverVelocity += _serverAcceleration * dt; _serverVelocity *= powf(1.0f - _body->getLinearDamping(), dt); @@ -291,10 +296,6 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { return true; } - if (_entity->shouldSuppressEdits()) { - return false; - } - // Else we measure the error between current and extrapolated transform (according to expected behavior // of remote EntitySimulation) and return true if the error is significant. From 8b72f6e7c61b206901d72d0e2eae920395e0b16a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 13:50:43 -0700 Subject: [PATCH 04/33] tweak --- interface/src/avatar/AvatarActionHold.cpp | 3 --- libraries/physics/src/EntityMotionState.cpp | 9 ++++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index ced5c83b08..582c636a7a 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -65,9 +65,6 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { gotLock = withTryWriteLock([&]{ if (_positionalTarget != position || _rotationalTarget != rotation) { auto ownerEntity = _ownerEntity.lock(); - if (ownerEntity) { - ownerEntity->setActionDataDirty(true); - } _positionalTarget = position; _rotationalTarget = rotation; } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 6be9938aff..5cfdd4125f 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -280,11 +280,6 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { } _lastStep = simulationStep; - - if (_entity->shouldSuppressEdits()) { - return false; - } - if (glm::length2(_serverVelocity) > 0.0f) { _serverVelocity += _serverAcceleration * dt; _serverVelocity *= powf(1.0f - _body->getLinearDamping(), dt); @@ -296,6 +291,10 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { return true; } + if (_entity->shouldSuppressEdits()) { + return false; + } + // Else we measure the error between current and extrapolated transform (according to expected behavior // of remote EntitySimulation) and return true if the error is significant. From fcbb107bc0aaf137a3262aef9bbca0413d1a6541 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 14:13:53 -0700 Subject: [PATCH 05/33] tweak --- interface/src/avatar/AvatarActionHold.cpp | 7 ++----- libraries/entities/src/EntityItemProperties.h | 7 ++++++- libraries/physics/src/ObjectActionSpring.cpp | 3 +-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 582c636a7a..fa2e40f19e 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -63,11 +63,8 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { if (gotLock) { gotLock = withTryWriteLock([&]{ - if (_positionalTarget != position || _rotationalTarget != rotation) { - auto ownerEntity = _ownerEntity.lock(); - _positionalTarget = position; - _rotationalTarget = rotation; - } + _positionalTarget = position; + _rotationalTarget = rotation; }); } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 22a4a298ef..51fa2eee75 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -370,7 +370,12 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelSurfaceStyle, voxelSurfaceStyle, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Href, href, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Description, description, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, ActionData, actionData, ""); + + // DEBUG_PROPERTY_IF_CHANGED(debug, properties, ActionData, actionData, ""); + if (properties.actionDataChanged()) { + debug << " " << "actionData" << ":" << properties.getActionData().toHex() << "" << "\n"; + } + DEBUG_PROPERTY_IF_CHANGED(debug, properties, XTextureURL, xTextureURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, YTextureURL, yTextureURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ZTextureURL, zTextureURL, ""); diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index 7d0bab5143..8b936a96e9 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -38,6 +38,7 @@ ObjectActionSpring::~ObjectActionSpring() { } void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { + // don't risk hanging the thread running the physics simulation auto lockResult = withTryReadLock([&]{ auto ownerEntity = _ownerEntity.lock(); if (!ownerEntity) { @@ -100,9 +101,7 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { } }); if (!lockResult) { - // don't risk hanging the thread running the physics simulation qDebug() << "ObjectActionSpring::updateActionWorker lock failed"; - return; } } From 755b9719060483faebaacc0d176f610eb12ad2a3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 14:31:52 -0700 Subject: [PATCH 06/33] tweak --- examples/controllers/handControllerGrab.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index f4bc7496da..9e7ad15179 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -339,11 +339,12 @@ function MyController(hand, triggerAction) { var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", "gravity", "ignoreForCollisions"]); + var now = Date.now(); // add the action and initialize some variables this.currentObjectPosition = grabbedProperties.position; this.currentObjectRotation = grabbedProperties.rotation; - this.currentObjectTime = Date.now(); + this.currentObjectTime = now; this.handPreviousPosition = handControllerPosition; this.handPreviousRotation = handRotation; @@ -359,6 +360,7 @@ function MyController(hand, triggerAction) { if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } + this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); if (this.actionID !== null) { this.setState(STATE_CONTINUE_DISTANCE_HOLDING); @@ -454,9 +456,11 @@ function MyController(hand, triggerAction) { angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, lifetime: ACTION_LIFETIME }); + this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); }; this.nearGrabbing = function() { + var now = Date.now(); if (this.triggerSmoothedReleased()) { this.setState(STATE_RELEASE); @@ -490,6 +494,7 @@ function MyController(hand, triggerAction) { if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } else { + this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); this.setState(STATE_CONTINUE_NEAR_GRABBING); if (this.hand === RIGHT_HAND) { Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); @@ -529,9 +534,13 @@ function MyController(hand, triggerAction) { this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); - Entities.updateAction(this.grabbedEntity, this.actionID, { - lifetime: ACTION_LIFETIME - }); + if (this.actionTimeout - now < MSEC_PER_SEC) { + // if less than a second left, refresh the actions lifetime + Entities.updateAction(this.grabbedEntity, this.actionID, { + lifetime: ACTION_LIFETIME + }); + this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); + } }; this.nearGrabbingNonColliding = function() { From 257e3845deb3a651dba582deca112d021312ddc7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 14:45:20 -0700 Subject: [PATCH 07/33] get action type correct --- interface/src/avatar/AvatarActionHold.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index fa2e40f19e..a035c9e514 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -159,7 +159,7 @@ QByteArray AvatarActionHold::serialize() const { QByteArray serializedActionArguments; QDataStream dataStream(&serializedActionArguments, QIODevice::WriteOnly); - dataStream << ACTION_TYPE_SPRING; + dataStream << ACTION_TYPE_HOLD; dataStream << getID(); dataStream << AvatarActionHold::holdVersion; From 4fa85441b824774dfae0a1a6d1ea4c68382c4463 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 15:14:34 -0700 Subject: [PATCH 08/33] tweak --- interface/src/avatar/AvatarActionHold.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index a035c9e514..e4c63da026 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -110,11 +110,11 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { ok = true; auto myAvatar = DependencyManager::get()->getMyAvatar(); auto holderID = myAvatar->getSessionUUID(); - QString holderIDString = - EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); - if (ok) { - holderID = QUuid(holderIDString); - } + // QString holderIDString = + // EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); + // if (ok) { + // holderID = QUuid(holderIDString); + // } if (relativePosition != _relativePosition || relativeRotation != _relativeRotation From 2ecb7e8d29251382f3b00254aa24e9acc2674b62 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 16:19:12 -0700 Subject: [PATCH 09/33] fix bug that was making action deletes fail --- assignment-client/src/AssignmentAction.cpp | 1 + interface/src/avatar/AvatarActionHold.cpp | 5 ----- libraries/entities/src/EntityItem.cpp | 6 ++++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/AssignmentAction.cpp b/assignment-client/src/AssignmentAction.cpp index 8b5650ee42..107a80cf14 100644 --- a/assignment-client/src/AssignmentAction.cpp +++ b/assignment-client/src/AssignmentAction.cpp @@ -25,6 +25,7 @@ AssignmentAction::~AssignmentAction() { void AssignmentAction::removeFromSimulation(EntitySimulation* simulation) const { simulation->removeAction(_id); + simulation->applyActionChanges(); } QByteArray AssignmentAction::serialize() const { diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index e4c63da026..60f1b31625 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -110,11 +110,6 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { ok = true; auto myAvatar = DependencyManager::get()->getMyAvatar(); auto holderID = myAvatar->getSessionUUID(); - // QString holderIDString = - // EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); - // if (ok) { - // holderID = QUuid(holderIDString); - // } if (relativePosition != _relativePosition || relativeRotation != _relativeRotation diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index cb141c930d..3cd7055d1d 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1720,9 +1720,11 @@ void EntityItem::setActionData(QByteArray actionData) { void EntityItem::setActionDataInternal(QByteArray actionData) { assertWriteLocked(); + if (_allActionsDataCache != actionData) { + _allActionsDataCache = actionData; + deserializeActionsInternal(); + } checkWaitingToRemove(); - _allActionsDataCache = actionData; - deserializeActionsInternal(); } void EntityItem::serializeActions(bool& success, QByteArray& result) const { From 4402242c3c5c60467449bc2245fcb4bccf0bb684 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 16:27:40 -0700 Subject: [PATCH 10/33] allow an action to suppress sending of physics related edits to the entity-server --- interface/src/avatar/AvatarActionHold.h | 2 ++ libraries/entities/src/EntityActionInterface.h | 2 ++ libraries/entities/src/EntityItem.cpp | 5 +++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index 613d2ef3a3..ff8d32891b 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -30,6 +30,8 @@ public: QByteArray serialize() const; virtual void deserialize(QByteArray serializedArguments); + virtual bool shouldSuppressEdits() { return true; } + private: static const uint16_t holdVersion; diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index 57f605c3e3..957071bd42 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -51,6 +51,8 @@ public: bool locallyAddedButNotYetReceived = false; + virtual bool shouldSuppressEdits() { return false; } + protected: virtual glm::vec3 getPosition() = 0; virtual void setPosition(glm::vec3 position) = 0; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 3cd7055d1d..c9f950bb61 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1794,8 +1794,9 @@ QVariantMap EntityItem::getActionArguments(const QUuid& actionID) const { bool EntityItem::shouldSuppressEdits() const { QHash::const_iterator i = _objectActions.begin(); while (i != _objectActions.end()) { - // XXX - return true; + if (i.value()->shouldSuppressEdits()) { + return true; + } } return false; From 644076214edfa8d61bc49eef71f6be065a42fe14 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 16:55:04 -0700 Subject: [PATCH 11/33] fix hang --- libraries/entities/src/EntityItem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index c9f950bb61..c9c431fd32 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1797,6 +1797,7 @@ bool EntityItem::shouldSuppressEdits() const { if (i.value()->shouldSuppressEdits()) { return true; } + i++; } return false; From 74ced250c11ac031bf87af38e539128bb409f89b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 17:18:28 -0700 Subject: [PATCH 12/33] don't compress joint rotations --- libraries/avatars/src/AvatarData.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index a9ff9541ea..8a93cbbac7 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -320,7 +320,11 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { for (int i = 0; i < _jointData.size(); i ++) { const JointData& data = _jointData[ i ]; if (validity & (1 << validityBit)) { - destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation); + + // destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation); + memcpy(destinationBuffer, &data.rotation, sizeof(glm::quat)); + destinationBuffer += sizeof(glm::quat); + } if (++validityBit == BITS_IN_BYTE) { validityBit = 0; @@ -704,7 +708,10 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { if (validRotations[i]) { _hasNewJointRotations = true; data.rotationSet = true; - sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation); + + // sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation); + memcpy(&data.rotation, sourceBuffer, sizeof(glm::quat)); + sourceBuffer += sizeof(glm::quat); } } } // numJoints * 8 bytes From f61a005ebcda1b54e7ddd7045facffb5c441f43c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 13 Oct 2015 17:47:41 -0700 Subject: [PATCH 13/33] cleanups --- libraries/avatars/src/AvatarData.cpp | 11 ++--------- libraries/entities/src/EntityItemProperties.h | 3 --- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 8a93cbbac7..a9ff9541ea 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -320,11 +320,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { for (int i = 0; i < _jointData.size(); i ++) { const JointData& data = _jointData[ i ]; if (validity & (1 << validityBit)) { - - // destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation); - memcpy(destinationBuffer, &data.rotation, sizeof(glm::quat)); - destinationBuffer += sizeof(glm::quat); - + destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation); } if (++validityBit == BITS_IN_BYTE) { validityBit = 0; @@ -708,10 +704,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { if (validRotations[i]) { _hasNewJointRotations = true; data.rotationSet = true; - - // sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation); - memcpy(&data.rotation, sourceBuffer, sizeof(glm::quat)); - sourceBuffer += sizeof(glm::quat); + sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation); } } } // numJoints * 8 bytes diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 51fa2eee75..06f90ffd42 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -370,12 +370,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelSurfaceStyle, voxelSurfaceStyle, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Href, href, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Description, description, ""); - - // DEBUG_PROPERTY_IF_CHANGED(debug, properties, ActionData, actionData, ""); if (properties.actionDataChanged()) { debug << " " << "actionData" << ":" << properties.getActionData().toHex() << "" << "\n"; } - DEBUG_PROPERTY_IF_CHANGED(debug, properties, XTextureURL, xTextureURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, YTextureURL, yTextureURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ZTextureURL, zTextureURL, ""); From 742cc0f511fb692a3824fb9669f7288c07e3497f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 06:17:55 -0700 Subject: [PATCH 14/33] rename a function --- interface/src/avatar/AvatarActionHold.h | 2 +- libraries/entities/src/EntityActionInterface.h | 2 +- libraries/entities/src/EntityItem.cpp | 4 ++-- libraries/entities/src/EntityItem.h | 2 +- libraries/physics/src/EntityMotionState.cpp | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index ff8d32891b..3cc70ced09 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -30,7 +30,7 @@ public: QByteArray serialize() const; virtual void deserialize(QByteArray serializedArguments); - virtual bool shouldSuppressEdits() { return true; } + virtual bool shouldSuppressLocationEdits() { return true; } private: static const uint16_t holdVersion; diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index 957071bd42..44c269f336 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -51,7 +51,7 @@ public: bool locallyAddedButNotYetReceived = false; - virtual bool shouldSuppressEdits() { return false; } + virtual bool shouldSuppressLocationEdits() { return false; } protected: virtual glm::vec3 getPosition() = 0; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index c9c431fd32..5b72ac62c1 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1791,10 +1791,10 @@ QVariantMap EntityItem::getActionArguments(const QUuid& actionID) const { return result; } -bool EntityItem::shouldSuppressEdits() const { +bool EntityItem::shouldSuppressLocationEdits() const { QHash::const_iterator i = _objectActions.begin(); while (i != _objectActions.end()) { - if (i.value()->shouldSuppressEdits()) { + if (i.value()->shouldSuppressLocationEdits()) { return true; } i++; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 59651bfaf0..cc8fa6c00d 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -424,7 +424,7 @@ public: QVariantMap getActionArguments(const QUuid& actionID) const; void deserializeActions(); void setActionDataDirty(bool value) const { _actionDataDirty = value; } - bool shouldSuppressEdits() const; + bool shouldSuppressLocationEdits() const; protected: diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 5cfdd4125f..2621347373 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -291,7 +291,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { return true; } - if (_entity->shouldSuppressEdits()) { + if (_entity->shouldSuppressLocationEdits()) { return false; } From 2a9b1c0fc37abc27ebde5142b2cc33e443156c72 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 09:31:29 -0700 Subject: [PATCH 15/33] fix refresh of hold action --- examples/controllers/handControllerGrab.js | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 9e7ad15179..ee16eadeed 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -443,7 +443,9 @@ function MyController(hand, triggerAction) { this.currentObjectTime = now; // this doubles hand rotation - var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), Quat.inverse(this.handPreviousRotation)); + var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, + DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), + Quat.inverse(this.handPreviousRotation)); this.handPreviousRotation = handRotation; this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation); @@ -469,7 +471,7 @@ function MyController(hand, triggerAction) { this.lineOff(); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", "gravity", "ignoreForCollisions"]); this.activateEntity(this.grabbedEntity, grabbedProperties); @@ -477,18 +479,18 @@ function MyController(hand, triggerAction) { var handPosition = this.getHandPosition(); var objectRotation = grabbedProperties.rotation; - var offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); + this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); var currentObjectPosition = grabbedProperties.position; var offset = Vec3.subtract(currentObjectPosition, handPosition); - var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); + 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: offsetPosition, - relativeRotation: offsetRotation, + relativePosition: this.offsetPosition, + relativeRotation: this.offsetRotation, lifetime: ACTION_LIFETIME }); if (this.actionID === NULL_ACTION_ID) { @@ -516,10 +518,10 @@ function MyController(hand, triggerAction) { return; } - // Keep track of the fingertip velocity to impart when we release the object - // Note that the idea of using a constant 'tip' velocity regardless of the + // Keep track of the fingertip velocity to impart when we release the object. + // Note that the idea of using a constant 'tip' velocity regardless of the // object's actual held offset is an idea intended to make it easier to throw things: - // Because we might catch something or transfer it between hands without a good idea + // Because we might catch something or transfer it between hands without a good idea // of it's actual offset, let's try imparting a velocity which is at a fixed radius // from the palm. @@ -537,6 +539,10 @@ function MyController(hand, triggerAction) { if (this.actionTimeout - now < MSEC_PER_SEC) { // if less than a second left, refresh the actions lifetime Entities.updateAction(this.grabbedEntity, this.actionID, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: this.offsetPosition, + relativeRotation: this.offsetRotation, lifetime: ACTION_LIFETIME }); this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); From 77bb11675d1c1ad7b257b6a34f2d761f994dcc5f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 09:31:44 -0700 Subject: [PATCH 16/33] terse entity-edit logging --- .../entities/src/AnimationPropertyGroup.cpp | 13 + .../entities/src/AnimationPropertyGroup.h | 1 + .../entities/src/AtmospherePropertyGroup.cpp | 24 ++ .../entities/src/AtmospherePropertyGroup.h | 3 +- .../entities/src/EntityItemProperties.cpp | 251 ++++++++++++++++++ libraries/entities/src/EntityItemProperties.h | 2 + libraries/entities/src/EntityTree.cpp | 7 +- libraries/entities/src/PropertyGroup.h | 1 + .../entities/src/SkyboxPropertyGroup.cpp | 9 + libraries/entities/src/SkyboxPropertyGroup.h | 1 + libraries/entities/src/StagePropertyGroup.cpp | 21 ++ libraries/entities/src/StagePropertyGroup.h | 1 + 12 files changed, 331 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index d1da465079..f9d8c07443 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -163,6 +163,19 @@ void AnimationPropertyGroup::debugDump() const { qDebug() << "currentFrame:" << getCurrentFrame() << " has changed:" << currentFrameChanged(); } +void AnimationPropertyGroup::listChangedProperties(QList& out) { + if (urlChanged()) { + out << "animation-url"; + } + if (fpsChanged()) { + out << "animation-fps"; + } + if (currentFrameChanged()) { + out << "animation-currentFrame"; + } +} + + bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index d0d218f4b3..8c40b0c036 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -37,6 +37,7 @@ public: virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); virtual void debugDump() const; + virtual void listChangedProperties(QList& out); virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, diff --git a/libraries/entities/src/AtmospherePropertyGroup.cpp b/libraries/entities/src/AtmospherePropertyGroup.cpp index 090fdb6c6f..8e7a5a5262 100644 --- a/libraries/entities/src/AtmospherePropertyGroup.cpp +++ b/libraries/entities/src/AtmospherePropertyGroup.cpp @@ -54,6 +54,30 @@ void AtmospherePropertyGroup::debugDump() const { qDebug() << " Has Stars:" << getHasStars() << " has changed:" << hasStarsChanged(); } +void AtmospherePropertyGroup::listChangedProperties(QList& out) { + if (centerChanged()) { + out << "center"; + } + if (innerRadiusChanged()) { + out << "innerRadius"; + } + if (outerRadiusChanged()) { + out << "outerRadius"; + } + if (mieScatteringChanged()) { + out << "mieScattering"; + } + if (rayleighScatteringChanged()) { + out << "rayleighScattering"; + } + if (scatteringWavelengthsChanged()) { + out << "scatteringWavelengths"; + } + if (hasStarsChanged()) { + out << "hasStars"; + } +} + bool AtmospherePropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, diff --git a/libraries/entities/src/AtmospherePropertyGroup.h b/libraries/entities/src/AtmospherePropertyGroup.h index 661d91087b..1d43c848b8 100644 --- a/libraries/entities/src/AtmospherePropertyGroup.h +++ b/libraries/entities/src/AtmospherePropertyGroup.h @@ -53,6 +53,7 @@ public: virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); virtual void debugDump() const; + virtual void listChangedProperties(QList& out); virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, @@ -87,7 +88,7 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged); - + static const glm::vec3 DEFAULT_CENTER; static const float DEFAULT_INNER_RADIUS; static const float DEFAULT_OUTER_RADIUS; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 4cbf7a043c..19c8f779b4 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1519,3 +1519,254 @@ void EntityItemProperties::setSimulationOwner(const QByteArray& data) { _simulationOwnerChanged = true; } } + +QList EntityItemProperties::listChangedProperties() { + QList out; + if (containsPositionChange()) { + out += "posistion"; + } + if (dimensionsChanged()) { + out += "dimensions"; + } + if (velocityChanged()) { + out += "velocity"; + } + if (nameChanged()) { + out += "name"; + } + if (visibleChanged()) { + out += "visible"; + } + if (rotationChanged()) { + out += "rotation"; + } + if (densityChanged()) { + out += "density"; + } + if (gravityChanged()) { + out += "gravity"; + } + if (accelerationChanged()) { + out += "acceleration"; + } + if (dampingChanged()) { + out += "damping"; + } + if (restitutionChanged()) { + out += "restitution"; + } + if (frictionChanged()) { + out += "friction"; + } + if (lifetimeChanged()) { + out += "lifetime"; + } + if (scriptChanged()) { + out += "script"; + } + if (scriptTimestampChanged()) { + out += "scriptTimestamp"; + } + if (collisionSoundURLChanged()) { + out += "collisionSoundURL"; + } + if (colorChanged()) { + out += "color"; + } + if (colorSpreadChanged()) { + out += "colorSpread"; + } + if (colorStartChanged()) { + out += "colorStart"; + } + if (colorFinishChanged()) { + out += "colorFinish"; + } + if (alphaChanged()) { + out += "alpha"; + } + if (alphaSpreadChanged()) { + out += "alphaSpread"; + } + if (alphaStartChanged()) { + out += "alphaStart"; + } + if (alphaFinishChanged()) { + out += "alphaFinish"; + } + if (modelURLChanged()) { + out += "modelURL"; + } + if (compoundShapeURLChanged()) { + out += "compoundShapeURL"; + } + if (registrationPointChanged()) { + out += "registrationPoint"; + } + if (angularVelocityChanged()) { + out += "angularVelocity"; + } + if (angularDampingChanged()) { + out += "angularDamping"; + } + if (ignoreForCollisionsChanged()) { + out += "ignoreForCollisions"; + } + if (collisionsWillMoveChanged()) { + out += "collisionsWillMove"; + } + if (isSpotlightChanged()) { + out += "isSpotlight"; + } + if (intensityChanged()) { + out += "intensity"; + } + if (exponentChanged()) { + out += "exponent"; + } + if (cutoffChanged()) { + out += "cutoff"; + } + if (lockedChanged()) { + out += "locked"; + } + if (texturesChanged()) { + out += "textures"; + } + if (userDataChanged()) { + out += "userData"; + } + if (simulationOwnerChanged()) { + out += "simulationOwner"; + } + if (textChanged()) { + out += "text"; + } + if (lineHeightChanged()) { + out += "lineHeight"; + } + if (textColorChanged()) { + out += "textColor"; + } + if (backgroundColorChanged()) { + out += "backgroundColor"; + } + if (shapeTypeChanged()) { + out += "shapeType"; + } + if (maxParticlesChanged()) { + out += "maxParticles"; + } + if (lifespanChanged()) { + out += "lifespan"; + } + if (isEmittingChanged()) { + out += "isEmitting"; + } + if (emitRateChanged()) { + out += "emitRate"; + } + if (emitSpeedChanged()) { + out += "emitSpeed"; + } + if (speedSpreadChanged()) { + out += "speedSpread"; + } + if (emitOrientationChanged()) { + out += "emitOrientation"; + } + if (emitDimensionsChanged()) { + out += "emitDimensions"; + } + if (emitRadiusStartChanged()) { + out += "emitRadiusStart"; + } + if (polarStartChanged()) { + out += "polarStart"; + } + if (polarFinishChanged()) { + out += "polarFinish"; + } + if (azimuthStartChanged()) { + out += "azimuthStart"; + } + if (azimuthFinishChanged()) { + out += "azimuthFinish"; + } + if (emitAccelerationChanged()) { + out += "emitAcceleration"; + } + if (accelerationSpreadChanged()) { + out += "accelerationSpread"; + } + if (particleRadiusChanged()) { + out += "particleRadius"; + } + if (radiusSpreadChanged()) { + out += "radiusSpread"; + } + if (radiusStartChanged()) { + out += "radiusStart"; + } + if (radiusFinishChanged()) { + out += "radiusFinish"; + } + if (marketplaceIDChanged()) { + out += "marketplaceID"; + } + if (backgroundModeChanged()) { + out += "backgroundMode"; + } + if (voxelVolumeSizeChanged()) { + out += "voxelVolumeSize"; + } + if (voxelDataChanged()) { + out += "voxelData"; + } + if (voxelSurfaceStyleChanged()) { + out += "voxelSurfaceStyle"; + } + if (hrefChanged()) { + out += "href"; + } + if (descriptionChanged()) { + out += "description"; + } + if (actionDataChanged()) { + out += "actionData"; + } + if (xTextureURLChanged()) { + out += "xTextureURL"; + } + if (yTextureURLChanged()) { + out += "yTextureURL"; + } + if (zTextureURLChanged()) { + out += "zTextureURL"; + } + if (xNNeighborIDChanged()) { + out += "xNNeighborID"; + } + if (yNNeighborIDChanged()) { + out += "yNNeighborID"; + } + if (zNNeighborIDChanged()) { + out += "zNNeighborID"; + } + if (xPNeighborIDChanged()) { + out += "xPNeighborID"; + } + if (yPNeighborIDChanged()) { + out += "yPNeighborID"; + } + if (zPNeighborIDChanged()) { + out += "zPNeighborID"; + } + + getAnimation().listChangedProperties(out); + getAtmosphere().listChangedProperties(out); + getSkybox().listChangedProperties(out); + getStage().listChangedProperties(out); + + return out; +} diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 06f90ffd42..4ed7454c17 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -253,6 +253,8 @@ public: void setActionDataDirty() { _actionDataChanged = true; } + QList listChangedProperties(); + private: QUuid _id; bool _idSet; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index c4c02d364f..b3e639747f 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -610,8 +610,11 @@ int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* edi // if the EntityItem exists, then update it startLogging = usecTimestampNow(); if (wantEditLogging()) { - qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID; - qCDebug(entities) << " properties:" << properties; + + // qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID; + // qCDebug(entities) << " properties:" << properties; + + qCDebug(entities) << "edit" << entityItemID.toString() << properties.listChangedProperties(); } endLogging = usecTimestampNow(); diff --git a/libraries/entities/src/PropertyGroup.h b/libraries/entities/src/PropertyGroup.h index 27d35fa714..138ee020c1 100644 --- a/libraries/entities/src/PropertyGroup.h +++ b/libraries/entities/src/PropertyGroup.h @@ -57,6 +57,7 @@ public: virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const = 0; virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) = 0; virtual void debugDump() const { } + virtual void listChangedProperties(QList& out) { } virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, diff --git a/libraries/entities/src/SkyboxPropertyGroup.cpp b/libraries/entities/src/SkyboxPropertyGroup.cpp index d291627d1e..0fd00bfe6e 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.cpp +++ b/libraries/entities/src/SkyboxPropertyGroup.cpp @@ -33,6 +33,15 @@ void SkyboxPropertyGroup::debugDump() const { qDebug() << " URL:" << getURL() << " has changed:" << urlChanged(); } +void SkyboxPropertyGroup::listChangedProperties(QList& out) { + if (colorChanged()) { + out << "skybox-color"; + } + if (urlChanged()) { + out << "skybox-url"; + } +} + bool SkyboxPropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, diff --git a/libraries/entities/src/SkyboxPropertyGroup.h b/libraries/entities/src/SkyboxPropertyGroup.h index 2ebfcfda14..745f762821 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.h +++ b/libraries/entities/src/SkyboxPropertyGroup.h @@ -33,6 +33,7 @@ public: virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); virtual void debugDump() const; + virtual void listChangedProperties(QList& out); virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, diff --git a/libraries/entities/src/StagePropertyGroup.cpp b/libraries/entities/src/StagePropertyGroup.cpp index 629f65b72f..0c10795d6f 100644 --- a/libraries/entities/src/StagePropertyGroup.cpp +++ b/libraries/entities/src/StagePropertyGroup.cpp @@ -66,6 +66,27 @@ void StagePropertyGroup::debugDump() const { qDebug() << " _automaticHourDay:" << _automaticHourDay; } +void StagePropertyGroup::listChangedProperties(QList& out) { + if (sunModelEnabledChanged()) { + out << "stage-sunModelEnabled"; + } + if (latitudeChanged()) { + out << "stage-latitude"; + } + if (altitudeChanged()) { + out << "stage-altitude"; + } + if (dayChanged()) { + out << "stage-day"; + } + if (hourChanged()) { + out << "stage-hour"; + } + if (automaticHourDayChanged()) { + out << "stage-automaticHourDay"; + } +} + bool StagePropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, diff --git a/libraries/entities/src/StagePropertyGroup.h b/libraries/entities/src/StagePropertyGroup.h index 95964f8264..c25a1e629e 100644 --- a/libraries/entities/src/StagePropertyGroup.h +++ b/libraries/entities/src/StagePropertyGroup.h @@ -33,6 +33,7 @@ public: virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); virtual void debugDump() const; + virtual void listChangedProperties(QList& out); virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, From 9a9e5b962e6437c7e2d85b12b8af305e7d5886f4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 09:45:35 -0700 Subject: [PATCH 17/33] make edit logging terse vs not a domain-server setting --- assignment-client/src/entities/EntityServer.cpp | 4 ++++ domain-server/resources/describe-settings.json | 8 ++++++++ libraries/entities/src/EntityTree.cpp | 15 +++++++++------ libraries/entities/src/EntityTree.h | 4 ++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index bdd5728246..f2a4c2664a 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -147,9 +147,13 @@ bool EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio readOptionBool(QString("wantEditLogging"), settingsSectionObject, wantEditLogging); qDebug("wantEditLogging=%s", debug::valueOf(wantEditLogging)); + bool wantTerseEditLogging = false; + readOptionBool(QString("wantTerseEditLogging"), settingsSectionObject, wantTerseEditLogging); + qDebug("wantTerseEditLogging=%s", debug::valueOf(wantTerseEditLogging)); EntityTreePointer tree = std::static_pointer_cast(_tree); tree->setWantEditLogging(wantEditLogging); + tree->setWantTerseEditLogging(wantTerseEditLogging); return true; } diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index eb1c478489..e0038117f0 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -484,6 +484,14 @@ "default": false, "advanced": true }, + { + "name": "wantTerseEditLogging", + "type": "checkbox", + "label": "Edit Logging (Terse)", + "help": "Logging of all edits to entities", + "default": false, + "advanced": true + }, { "name": "verboseDebug", "type": "checkbox", diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index b3e639747f..fa2153f059 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -610,10 +610,10 @@ int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* edi // if the EntityItem exists, then update it startLogging = usecTimestampNow(); if (wantEditLogging()) { - - // qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID; - // qCDebug(entities) << " properties:" << properties; - + qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID; + qCDebug(entities) << " properties:" << properties; + } + if (wantTerseEditLogging()) { qCDebug(entities) << "edit" << entityItemID.toString() << properties.listChangedProperties(); } endLogging = usecTimestampNow(); @@ -641,6 +641,9 @@ int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* edi << newEntity->getEntityItemID(); qCDebug(entities) << " properties:" << properties; } + if (wantTerseEditLogging()) { + qCDebug(entities) << "add" << entityItemID.toString() << properties.listChangedProperties(); + } endLogging = usecTimestampNow(); } @@ -872,7 +875,7 @@ int EntityTree::processEraseMessage(NLPacket& packet, const SharedNodePointer& s EntityItemID entityItemID(entityID); entityItemIDsToDelete << entityItemID; - if (wantEditLogging()) { + if (wantEditLogging() || wantTerseEditLogging()) { qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID; } @@ -916,7 +919,7 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons EntityItemID entityItemID(entityID); entityItemIDsToDelete << entityItemID; - if (wantEditLogging()) { + if (wantEditLogging() || wantTerseEditLogging()) { qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID; } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index dd1ee01969..ff84a79088 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -175,6 +175,9 @@ public: bool wantEditLogging() const { return _wantEditLogging; } void setWantEditLogging(bool value) { _wantEditLogging = value; } + bool wantTerseEditLogging() const { return _wantTerseEditLogging; } + void setWantTerseEditLogging(bool value) { _wantTerseEditLogging = value; } + bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues); bool readFromMap(QVariantMap& entityDescription); @@ -240,6 +243,7 @@ private: EntitySimulation* _simulation; bool _wantEditLogging = false; + bool _wantTerseEditLogging = false; void maybeNotifyNewCollisionSoundURL(const QString& oldCollisionSoundURL, const QString& newCollisionSoundURL); From fa2bf2b2d9f47335888dfcc1b4dda4384c9a0fb9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 11:43:03 -0700 Subject: [PATCH 18/33] tighten up locking in actions --- interface/src/avatar/AvatarActionHold.cpp | 179 ++++++++++-------- .../entities/src/EntityActionInterface.h | 20 +- libraries/entities/src/EntityItem.cpp | 5 +- libraries/physics/src/ObjectAction.cpp | 25 ++- 4 files changed, 135 insertions(+), 94 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 60f1b31625..7d38eb0f23 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -37,37 +37,41 @@ AvatarActionHold::~AvatarActionHold() { } void AvatarActionHold::updateActionWorker(float deltaTimeStep) { - QSharedPointer avatarManager = DependencyManager::get(); - AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID); - std::shared_ptr holdingAvatar = std::static_pointer_cast(holdingAvatarData); + bool gotLock = false; + glm::quat rotation; + glm::vec3 position; + std::shared_ptr holdingAvatar = nullptr; + + gotLock = withTryReadLock([&]{ + QSharedPointer avatarManager = DependencyManager::get(); + AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID); + holdingAvatar = std::static_pointer_cast(holdingAvatarData); + + if (holdingAvatar) { + glm::vec3 offset; + glm::vec3 palmPosition; + glm::quat palmRotation; + if (_hand == "right") { + palmPosition = holdingAvatar->getRightPalmPosition(); + palmRotation = holdingAvatar->getRightPalmRotation(); + } else { + palmPosition = holdingAvatar->getLeftPalmPosition(); + palmRotation = holdingAvatar->getLeftPalmRotation(); + } + + rotation = palmRotation * _relativeRotation; + offset = rotation * _relativePosition; + position = palmPosition + offset; + } + }); if (holdingAvatar) { - glm::quat rotation; - glm::vec3 position; - glm::vec3 offset; - bool gotLock = withTryReadLock([&]{ - glm::vec3 palmPosition; - glm::quat palmRotation; - if (_hand == "right") { - palmPosition = holdingAvatar->getRightPalmPosition(); - palmRotation = holdingAvatar->getRightPalmRotation(); - } else { - palmPosition = holdingAvatar->getLeftPalmPosition(); - palmRotation = holdingAvatar->getLeftPalmRotation(); - } - - rotation = palmRotation * _relativeRotation; - offset = rotation * _relativePosition; - position = palmPosition + offset; - }); - if (gotLock) { gotLock = withTryWriteLock([&]{ - _positionalTarget = position; - _rotationalTarget = rotation; - }); + _positionalTarget = position; + _rotationalTarget = rotation; + }); } - if (gotLock) { ObjectActionSpring::updateActionWorker(deltaTimeStep); } @@ -76,46 +80,61 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { bool AvatarActionHold::updateArguments(QVariantMap arguments) { - if (!ObjectAction::updateArguments(arguments)) { - return false; - } - bool ok = true; - glm::vec3 relativePosition = - EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); - if (!ok) { - relativePosition = _relativePosition; - } + glm::vec3 relativePosition; + glm::quat relativeRotation; + float timeScale; + QString hand; + QUuid holderID; + bool needUpdate = false; + bool updateArgumentsSuceeded = true; - ok = true; - glm::quat relativeRotation = - EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false); - if (!ok) { - relativeRotation = _relativeRotation; - } + withReadLock([&]{ + if (!ObjectAction::updateArguments(arguments)) { + updateArgumentsSuceeded = false; + return; + } + bool ok = true; + relativePosition = EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); + if (!ok) { + relativePosition = _relativePosition; + } - ok = true; - float timeScale = - EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false); - if (!ok) { - timeScale = _linearTimeScale; - } + ok = true; + relativeRotation = EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false); + if (!ok) { + relativeRotation = _relativeRotation; + } - ok = true; - QString hand = - EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); - if (!ok || !(hand == "left" || hand == "right")) { - hand = _hand; - } + ok = true; + timeScale = EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false); + if (!ok) { + timeScale = _linearTimeScale; + } - ok = true; - auto myAvatar = DependencyManager::get()->getMyAvatar(); - auto holderID = myAvatar->getSessionUUID(); + ok = true; + hand = EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); + if (!ok || !(hand == "left" || hand == "right")) { + hand = _hand; + } - if (relativePosition != _relativePosition + ok = true; + auto myAvatar = DependencyManager::get()->getMyAvatar(); + holderID = myAvatar->getSessionUUID(); + + if (relativePosition != _relativePosition || relativeRotation != _relativeRotation || timeScale != _linearTimeScale || hand != _hand || holderID != _holderID) { + needUpdate = true; + } + }); + + if (!updateArgumentsSuceeded) { + return false; + } + + if (needUpdate) { withWriteLock([&] { _relativePosition = relativePosition; _relativeRotation = relativeRotation; @@ -154,18 +173,20 @@ QByteArray AvatarActionHold::serialize() const { QByteArray serializedActionArguments; QDataStream dataStream(&serializedActionArguments, QIODevice::WriteOnly); - dataStream << ACTION_TYPE_HOLD; - dataStream << getID(); - dataStream << AvatarActionHold::holdVersion; + withReadLock([&]{ + dataStream << ACTION_TYPE_HOLD; + dataStream << getID(); + dataStream << AvatarActionHold::holdVersion; - dataStream << _holderID; - dataStream << _relativePosition; - dataStream << _relativeRotation; - dataStream << _linearTimeScale; - dataStream << _hand; + dataStream << _holderID; + dataStream << _relativePosition; + dataStream << _relativeRotation; + dataStream << _linearTimeScale; + dataStream << _hand; - dataStream << _expires; - dataStream << _tag; + dataStream << _expires; + dataStream << _tag; + }); return serializedActionArguments; } @@ -187,15 +208,21 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) { return; } - dataStream >> _holderID; - dataStream >> _relativePosition; - dataStream >> _relativeRotation; - dataStream >> _linearTimeScale; - _angularTimeScale = _linearTimeScale; - dataStream >> _hand; + withWriteLock([&]{ + dataStream >> _holderID; + dataStream >> _relativePosition; + dataStream >> _relativeRotation; + dataStream >> _linearTimeScale; + _angularTimeScale = _linearTimeScale; + dataStream >> _hand; - dataStream >> _expires; - dataStream >> _tag; + dataStream >> _expires; + dataStream >> _tag; - _active = true; + qDebug() << "deserialize hold: " << _holderID + << _relativePosition.x << _relativePosition.y << _relativePosition.z + << _hand; + + _active = true; + }); } diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index 44c269f336..49739e7da9 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -53,16 +53,6 @@ public: virtual bool shouldSuppressLocationEdits() { return false; } -protected: - virtual glm::vec3 getPosition() = 0; - virtual void setPosition(glm::vec3 position) = 0; - virtual glm::quat getRotation() = 0; - virtual void setRotation(glm::quat rotation) = 0; - virtual glm::vec3 getLinearVelocity() = 0; - virtual void setLinearVelocity(glm::vec3 linearVelocity) = 0; - virtual glm::vec3 getAngularVelocity() = 0; - virtual void setAngularVelocity(glm::vec3 angularVelocity) = 0; - // these look in the arguments map for a named argument. if it's not found or isn't well formed, // ok will be set to false (note that it's never set to true -- set it to true before calling these). // if required is true, failure to extract an argument will cause a warning to be printed. @@ -77,6 +67,16 @@ protected: static QString extractStringArgument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok, bool required = true); +protected: + virtual glm::vec3 getPosition() = 0; + virtual void setPosition(glm::vec3 position) = 0; + virtual glm::quat getRotation() = 0; + virtual void setRotation(glm::quat rotation) = 0; + virtual glm::vec3 getLinearVelocity() = 0; + virtual void setLinearVelocity(glm::vec3 linearVelocity) = 0; + virtual glm::vec3 getAngularVelocity() = 0; + virtual void setAngularVelocity(glm::vec3 angularVelocity) = 0; + QUuid _id; EntityActionType _type; }; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 5b72ac62c1..56d68e910e 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1630,8 +1630,6 @@ void EntityItem::deserializeActionsInternal() { return; } - // Keep track of which actions got added or updated by the new actionData - EntityTreePointer entityTree = _element ? _element->getTree() : nullptr; assert(entityTree); EntitySimulation* simulation = entityTree ? entityTree->getSimulation() : nullptr; @@ -1643,6 +1641,7 @@ void EntityItem::deserializeActionsInternal() { serializedActionsStream >> serializedActions; } + // Keep track of which actions got added or updated by the new actionData QSet updated; foreach(QByteArray serializedAction, serializedActions) { @@ -1658,12 +1657,14 @@ void EntityItem::deserializeActionsInternal() { updated << actionID; if (_objectActions.contains(actionID)) { + qDebug() << "EntityItem::deserializeActionsInternal is UPDATING" << actionID; EntityActionPointer action = _objectActions[actionID]; // TODO: make sure types match? there isn't currently a way to // change the type of an existing action. action->deserialize(serializedAction); action->locallyAddedButNotYetReceived = false; } else { + qDebug() << "EntityItem::deserializeActionsInternal is ADDING" << actionID; auto actionFactory = DependencyManager::get(); EntityItemPointer entity = shared_from_this(); EntityActionPointer action = actionFactory->factoryBA(entity, serializedAction); diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 82395c21cf..2923bc20a9 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -24,20 +24,33 @@ ObjectAction::~ObjectAction() { } void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) { - if (_ownerEntity.expired()) { + bool ownerEntityExpired = false; + quint64 expiresWhen = 0; + + withReadLock([&]{ + ownerEntityExpired = _ownerEntity.expired(); + expiresWhen = _expires; + }); + + if (ownerEntityExpired) { qDebug() << "warning -- action with no entity removing self from btCollisionWorld."; btDynamicsWorld* dynamicsWorld = static_cast(collisionWorld); dynamicsWorld->removeAction(this); return; } - if (_expires > 0) { + if (expiresWhen > 0) { quint64 now = usecTimestampNow(); - if (now > _expires) { - EntityItemPointer ownerEntity = _ownerEntity.lock(); - _active = false; + if (now > expiresWhen) { + EntityItemPointer ownerEntity = nullptr; + QUuid myID; + withWriteLock([&]{ + ownerEntity = _ownerEntity.lock(); + _active = false; + myID = getID(); + }); if (ownerEntity) { - ownerEntity->removeAction(nullptr, getID()); + ownerEntity->removeAction(nullptr, myID); } } } From 07a4dc3a7fc5e7e522de6c9a51ebfb71e54094a3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 12:49:06 -0700 Subject: [PATCH 19/33] more lock fixing --- interface/src/avatar/AvatarActionHold.cpp | 15 +--- libraries/entities/src/EntityItem.cpp | 9 ++ libraries/physics/src/ObjectAction.cpp | 89 ++++++++++++-------- libraries/physics/src/ObjectActionOffset.cpp | 62 ++++++++------ libraries/physics/src/ObjectActionSpring.cpp | 82 ++++++++++-------- 5 files changed, 155 insertions(+), 102 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 7d38eb0f23..ce34306df4 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -86,13 +86,9 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { QString hand; QUuid holderID; bool needUpdate = false; - bool updateArgumentsSuceeded = true; + bool somethingChanged = ObjectAction::updateArguments(arguments); withReadLock([&]{ - if (!ObjectAction::updateArguments(arguments)) { - updateArgumentsSuceeded = false; - return; - } bool ok = true; relativePosition = EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); if (!ok) { @@ -121,7 +117,8 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { auto myAvatar = DependencyManager::get()->getMyAvatar(); holderID = myAvatar->getSessionUUID(); - if (relativePosition != _relativePosition + if (somethingChanged || + relativePosition != _relativePosition || relativeRotation != _relativeRotation || timeScale != _linearTimeScale || hand != _hand @@ -130,10 +127,6 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { } }); - if (!updateArgumentsSuceeded) { - return false; - } - if (needUpdate) { withWriteLock([&] { _relativePosition = relativePosition; @@ -221,7 +214,7 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) { qDebug() << "deserialize hold: " << _holderID << _relativePosition.x << _relativePosition.y << _relativePosition.z - << _hand; + << _hand << _expires; _active = true; }); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 56d68e910e..8fe5bea125 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1579,6 +1579,9 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* s } EntityActionPointer action = _objectActions[actionID]; + + qDebug() << "EntityItem::removeActionInternal clearing _ownerEntity"; + action->setOwnerEntity(nullptr); _objectActions.remove(actionID); @@ -1601,6 +1604,7 @@ bool EntityItem::clearActions(EntitySimulation* simulation) { const QUuid id = i.key(); EntityActionPointer action = _objectActions[id]; i = _objectActions.erase(i); + qDebug() << "EntityItem::clearActions clearing _ownerEntity"; action->setOwnerEntity(nullptr); action->removeFromSimulation(simulation); } @@ -1644,6 +1648,8 @@ void EntityItem::deserializeActionsInternal() { // Keep track of which actions got added or updated by the new actionData QSet updated; + qDebug() << "EntityItem::deserializeActionsInternal" << serializedActions.size(); + foreach(QByteArray serializedAction, serializedActions) { QDataStream serializedActionStream(serializedAction); EntityActionType actionType; @@ -1722,8 +1728,11 @@ void EntityItem::setActionData(QByteArray actionData) { void EntityItem::setActionDataInternal(QByteArray actionData) { assertWriteLocked(); if (_allActionsDataCache != actionData) { + qDebug() << "EntityItem::setActionDataInternal yes"; _allActionsDataCache = actionData; deserializeActionsInternal(); + } else { + qDebug() << "EntityItem::setActionDataInternal no"; } checkWaitingToRemove(); } diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 2923bc20a9..2f0de6d0ab 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -63,35 +63,48 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta } bool ObjectAction::updateArguments(QVariantMap arguments) { - bool lifetimeSet = true; - float lifetime = EntityActionInterface::extractFloatArgument("action", arguments, "lifetime", lifetimeSet, false); - if (lifetimeSet) { - quint64 now = usecTimestampNow(); - _expires = now + (quint64)(lifetime * USECS_PER_SECOND); - } else { - _expires = 0; - } + bool somethingChanged = false; - bool tagSet = true; - QString tag = EntityActionInterface::extractStringArgument("action", arguments, "tag", tagSet, false); - if (tagSet) { - _tag = tag; - } else { - tag = ""; - } + withWriteLock([&]{ + quint64 previousExpires = _expires; + QString previousTag = _tag; - return true; + bool lifetimeSet = true; + float lifetime = EntityActionInterface::extractFloatArgument("action", arguments, "lifetime", lifetimeSet, false); + if (lifetimeSet) { + quint64 now = usecTimestampNow(); + _expires = now + (quint64)(lifetime * USECS_PER_SECOND); + } else { + _expires = 0; + } + + bool tagSet = true; + QString tag = EntityActionInterface::extractStringArgument("action", arguments, "tag", tagSet, false); + if (tagSet) { + _tag = tag; + } else { + tag = ""; + } + + if (previousExpires != _expires || previousTag != _tag) { + somethingChanged = true; + } + }); + + return somethingChanged; } QVariantMap ObjectAction::getArguments() { QVariantMap arguments; - if (_expires == 0) { - arguments["lifetime"] = 0.0f; - } else { - quint64 now = usecTimestampNow(); - arguments["lifetime"] = (float)(_expires - now) / (float)USECS_PER_SECOND; - } - arguments["tag"] = _tag; + withReadLock([&]{ + if (_expires == 0) { + arguments["lifetime"] = 0.0f; + } else { + quint64 now = usecTimestampNow(); + arguments["lifetime"] = (float)(_expires - now) / (float)USECS_PER_SECOND; + } + arguments["tag"] = _tag; + }); return arguments; } @@ -100,20 +113,30 @@ void ObjectAction::debugDraw(btIDebugDraw* debugDrawer) { } void ObjectAction::removeFromSimulation(EntitySimulation* simulation) const { - simulation->removeAction(_id); + QUuid myID; + withReadLock([&]{ + myID = _id; + }); + simulation->removeAction(myID); } btRigidBody* ObjectAction::getRigidBody() { - auto ownerEntity = _ownerEntity.lock(); - if (!ownerEntity) { - return nullptr; + ObjectMotionState* motionState = nullptr; + withReadLock([&]{ + auto ownerEntity = _ownerEntity.lock(); + if (!ownerEntity) { + return; + } + void* physicsInfo = ownerEntity->getPhysicsInfo(); + if (!physicsInfo) { + return; + } + motionState = static_cast(physicsInfo); + }); + if (motionState) { + return motionState->getRigidBody(); } - void* physicsInfo = ownerEntity->getPhysicsInfo(); - if (!physicsInfo) { - return nullptr; - } - ObjectMotionState* motionState = static_cast(physicsInfo); - return motionState->getRigidBody(); + return nullptr; } glm::vec3 ObjectAction::getPosition() { diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index 448ec34689..ad5f49b3fb 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -80,35 +80,46 @@ void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) { bool ObjectActionOffset::updateArguments(QVariantMap arguments) { - if (!ObjectAction::updateArguments(arguments)) { - return false; - } - bool ok = true; - glm::vec3 pointToOffsetFrom = - EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", ok, true); - if (!ok) { - pointToOffsetFrom = _pointToOffsetFrom; - } + glm::vec3 pointToOffsetFrom; + float linearTimeScale; + float linearDistance; - ok = true; - float linearTimeScale = - EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", ok, false); - if (!ok) { - linearTimeScale = _linearTimeScale; - } + bool needUpdate = false; + bool somethingChanged = ObjectAction::updateArguments(arguments); - ok = true; - float linearDistance = - EntityActionInterface::extractFloatArgument("offset action", arguments, "linearDistance", ok, false); - if (!ok) { - linearDistance = _linearDistance; - } + withReadLock([&]{ + bool ok = true; + pointToOffsetFrom = + EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", ok, true); + if (!ok) { + pointToOffsetFrom = _pointToOffsetFrom; + } - // only change stuff if something actually changed - if (_pointToOffsetFrom != pointToOffsetFrom - || _linearTimeScale != linearTimeScale - || _linearDistance != linearDistance) { + ok = true; + linearTimeScale = + EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", ok, false); + if (!ok) { + linearTimeScale = _linearTimeScale; + } + ok = true; + linearDistance = + EntityActionInterface::extractFloatArgument("offset action", arguments, "linearDistance", ok, false); + if (!ok) { + linearDistance = _linearDistance; + } + + // only change stuff if something actually changed + if (somethingChanged || + _pointToOffsetFrom != pointToOffsetFrom || + _linearTimeScale != linearTimeScale || + _linearDistance != linearDistance) { + needUpdate = true; + } + }); + + + if (needUpdate) { withWriteLock([&] { _pointToOffsetFrom = pointToOffsetFrom; _linearTimeScale = linearTimeScale; @@ -118,6 +129,7 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { activateBody(); }); } + return true; } diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index 8b936a96e9..6c7507a9db 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -107,43 +107,52 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { const float MIN_TIMESCALE = 0.1f; + bool ObjectActionSpring::updateArguments(QVariantMap arguments) { - if (!ObjectAction::updateArguments(arguments)) { - return false; - } - // targets are required, spring-constants are optional - bool ok = true; - glm::vec3 positionalTarget = - EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false); - if (!ok) { - positionalTarget = _positionalTarget; - } - ok = true; - float linearTimeScale = - EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false); - if (!ok || linearTimeScale <= 0.0f) { - linearTimeScale = _linearTimeScale; - } + glm::vec3 positionalTarget; + float linearTimeScale; + glm::quat rotationalTarget; + float angularTimeScale; - ok = true; - glm::quat rotationalTarget = - EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false); - if (!ok) { - rotationalTarget = _rotationalTarget; - } + bool needUpdate = false; + bool somethingChanged = ObjectAction::updateArguments(arguments); + withReadLock([&]{ + // targets are required, spring-constants are optional + bool ok = true; + positionalTarget = EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false); + if (!ok) { + positionalTarget = _positionalTarget; + } + ok = true; + linearTimeScale = EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false); + if (!ok || linearTimeScale <= 0.0f) { + linearTimeScale = _linearTimeScale; + } - ok = true; - float angularTimeScale = - EntityActionInterface::extractFloatArgument("spring action", arguments, "angularTimeScale", ok, false); - if (!ok) { - angularTimeScale = _angularTimeScale; - } + ok = true; + rotationalTarget = EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false); + if (!ok) { + rotationalTarget = _rotationalTarget; + } - if (positionalTarget != _positionalTarget - || linearTimeScale != _linearTimeScale - || rotationalTarget != _rotationalTarget - || angularTimeScale != _angularTimeScale) { - // something changed + ok = true; + angularTimeScale = + EntityActionInterface::extractFloatArgument("spring action", arguments, "angularTimeScale", ok, false); + if (!ok) { + angularTimeScale = _angularTimeScale; + } + + if (somethingChanged || + positionalTarget != _positionalTarget || + linearTimeScale != _linearTimeScale || + rotationalTarget != _rotationalTarget || + angularTimeScale != _angularTimeScale) { + // something changed + needUpdate = true; + } + }); + + if (needUpdate) { withWriteLock([&] { _positionalTarget = positionalTarget; _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale)); @@ -151,8 +160,15 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale)); _active = true; activateBody(); + + auto ownerEntity = _ownerEntity.lock(); + if (ownerEntity) { + ownerEntity->setActionDataDirty(true); + } + }); } + return true; } From d72152da877283c16765e17d78ae0924d16161a1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 13:01:56 -0700 Subject: [PATCH 20/33] more locking --- interface/src/avatar/AvatarActionHold.cpp | 3 +-- libraries/physics/src/ObjectActionOffset.cpp | 7 ++++++- libraries/physics/src/ObjectActionSpring.cpp | 3 +-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index ce34306df4..59aebc23d8 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -136,15 +136,14 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { _angularTimeScale = _linearTimeScale; _hand = hand; _holderID = holderID; - _active = true; - activateBody(); auto ownerEntity = _ownerEntity.lock(); if (ownerEntity) { ownerEntity->setActionDataDirty(true); } }); + activateBody(); } return true; diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index ad5f49b3fb..4930d44f3c 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -126,8 +126,13 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { _linearDistance = linearDistance; _positionalTargetSet = true; _active = true; - activateBody(); + + auto ownerEntity = _ownerEntity.lock(); + if (ownerEntity) { + ownerEntity->setActionDataDirty(true); + } }); + activateBody(); } return true; diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index 6c7507a9db..242849db6f 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -159,14 +159,13 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { _rotationalTarget = rotationalTarget; _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale)); _active = true; - activateBody(); auto ownerEntity = _ownerEntity.lock(); if (ownerEntity) { ownerEntity->setActionDataDirty(true); } - }); + activateBody(); } return true; From 9937b6a3ef93b8d779ce0e66ff2fe75e2d30bb2d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 13:12:11 -0700 Subject: [PATCH 21/33] quiet some debugging --- interface/src/avatar/AvatarActionHold.cpp | 4 +++- libraries/entities/src/EntityItem.cpp | 10 ---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 59aebc23d8..f12909e809 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -211,9 +211,11 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) { dataStream >> _expires; dataStream >> _tag; - qDebug() << "deserialize hold: " << _holderID + #if WANT_DEBUG + qDebug() << "deserialize AvatarActionHold: " << _holderID << _relativePosition.x << _relativePosition.y << _relativePosition.z << _hand << _expires; + #endif _active = true; }); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 8fe5bea125..1ae0c481ac 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1580,8 +1580,6 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulation* s EntityActionPointer action = _objectActions[actionID]; - qDebug() << "EntityItem::removeActionInternal clearing _ownerEntity"; - action->setOwnerEntity(nullptr); _objectActions.remove(actionID); @@ -1604,7 +1602,6 @@ bool EntityItem::clearActions(EntitySimulation* simulation) { const QUuid id = i.key(); EntityActionPointer action = _objectActions[id]; i = _objectActions.erase(i); - qDebug() << "EntityItem::clearActions clearing _ownerEntity"; action->setOwnerEntity(nullptr); action->removeFromSimulation(simulation); } @@ -1648,8 +1645,6 @@ void EntityItem::deserializeActionsInternal() { // Keep track of which actions got added or updated by the new actionData QSet updated; - qDebug() << "EntityItem::deserializeActionsInternal" << serializedActions.size(); - foreach(QByteArray serializedAction, serializedActions) { QDataStream serializedActionStream(serializedAction); EntityActionType actionType; @@ -1663,14 +1658,12 @@ void EntityItem::deserializeActionsInternal() { updated << actionID; if (_objectActions.contains(actionID)) { - qDebug() << "EntityItem::deserializeActionsInternal is UPDATING" << actionID; EntityActionPointer action = _objectActions[actionID]; // TODO: make sure types match? there isn't currently a way to // change the type of an existing action. action->deserialize(serializedAction); action->locallyAddedButNotYetReceived = false; } else { - qDebug() << "EntityItem::deserializeActionsInternal is ADDING" << actionID; auto actionFactory = DependencyManager::get(); EntityItemPointer entity = shared_from_this(); EntityActionPointer action = actionFactory->factoryBA(entity, serializedAction); @@ -1728,11 +1721,8 @@ void EntityItem::setActionData(QByteArray actionData) { void EntityItem::setActionDataInternal(QByteArray actionData) { assertWriteLocked(); if (_allActionsDataCache != actionData) { - qDebug() << "EntityItem::setActionDataInternal yes"; _allActionsDataCache = actionData; deserializeActionsInternal(); - } else { - qDebug() << "EntityItem::setActionDataInternal no"; } checkWaitingToRemove(); } From 9a2aa9a337761d2afd602db460db2f012e9233a7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 13:40:20 -0700 Subject: [PATCH 22/33] locking --- assignment-client/src/AssignmentAction.cpp | 16 ++++++++++++---- assignment-client/src/AssignmentAction.h | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/AssignmentAction.cpp b/assignment-client/src/AssignmentAction.cpp index 107a80cf14..388f4123f6 100644 --- a/assignment-client/src/AssignmentAction.cpp +++ b/assignment-client/src/AssignmentAction.cpp @@ -24,16 +24,24 @@ AssignmentAction::~AssignmentAction() { } void AssignmentAction::removeFromSimulation(EntitySimulation* simulation) const { - simulation->removeAction(_id); - simulation->applyActionChanges(); + withReadLock([&]{ + simulation->removeAction(_id); + simulation->applyActionChanges(); + }); } QByteArray AssignmentAction::serialize() const { - return _data; + QByteArray result; + withReadLock([&]{ + result = _data; + }); + return result; } void AssignmentAction::deserialize(QByteArray serializedArguments) { - _data = serializedArguments; + withWriteLock([&]{ + _data = serializedArguments; + }); } bool AssignmentAction::updateArguments(QVariantMap arguments) { diff --git a/assignment-client/src/AssignmentAction.h b/assignment-client/src/AssignmentAction.h index 23720bd465..6b901c9766 100644 --- a/assignment-client/src/AssignmentAction.h +++ b/assignment-client/src/AssignmentAction.h @@ -19,7 +19,7 @@ #include "EntityActionInterface.h" -class AssignmentAction : public EntityActionInterface { +class AssignmentAction : public EntityActionInterface, public ReadWriteLockable { public: AssignmentAction(EntityActionType type, const QUuid& id, EntityItemPointer ownerEntity); virtual ~AssignmentAction(); From 5ce39b74fdcf338ac56e9a0ef78fd4d8abe0694b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 13:58:19 -0700 Subject: [PATCH 23/33] debugging --- interface/src/Application.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e0e5003830..7415e7d297 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2054,11 +2054,40 @@ void Application::checkFPS() { _timerStart.start(); } +uint64_t lastReport = usecTimestampNow(); // XXX + + void Application::idle() { if (_aboutToQuit) { return; // bail early, nothing to do here. } + + // XXX + { // XXX + uint64_t now = usecTimestampNow(); + if (now - lastReport > 4 * USECS_PER_SECOND) { + QSharedPointer avatarManager = DependencyManager::get(); + const AvatarHash& avatarHash = avatarManager->getAvatarHash(); + + glm::vec3 myLeftPalm = getMyAvatar()->getLeftPalmPosition(); + qDebug() << "my left palm:" << myLeftPalm; + + QHash::const_iterator i; + for (i = avatarHash.begin(); i != avatarHash.end(); ++i) { + std::shared_ptr otherAvatar = std::static_pointer_cast(i.value()); + if (otherAvatar->getSessionUUID() == getMyAvatar()->getSessionUUID()) { + continue; + } + glm::vec3 theirLeftPalm = otherAvatar->getLeftPalmPosition(); + qDebug() << "their left palm:" << theirLeftPalm; + }; + + lastReport = now; + } + } // XXX + // XXX + // depending on whether we're throttling or not. // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in // perpetuity and not expect events to get backed up. From 21519c6418d3566072b5784df5a7eb9e0fe5d833 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 14 Oct 2015 14:13:08 -0700 Subject: [PATCH 24/33] debugging --- interface/src/Application.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7415e7d297..733858dd7e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2066,12 +2066,14 @@ void Application::idle() { // XXX { // XXX uint64_t now = usecTimestampNow(); - if (now - lastReport > 4 * USECS_PER_SECOND) { + if (now - lastReport > 6 * USECS_PER_SECOND) { QSharedPointer avatarManager = DependencyManager::get(); const AvatarHash& avatarHash = avatarManager->getAvatarHash(); - glm::vec3 myLeftPalm = getMyAvatar()->getLeftPalmPosition(); - qDebug() << "my left palm:" << myLeftPalm; + qDebug() << "-----------------------"; + + qDebug() << "my left palm:" << getMyAvatar()->getLeftPalmPosition() + << " my chest:" << getMyAvatar()->getChestPosition(); QHash::const_iterator i; for (i = avatarHash.begin(); i != avatarHash.end(); ++i) { @@ -2079,8 +2081,8 @@ void Application::idle() { if (otherAvatar->getSessionUUID() == getMyAvatar()->getSessionUUID()) { continue; } - glm::vec3 theirLeftPalm = otherAvatar->getLeftPalmPosition(); - qDebug() << "their left palm:" << theirLeftPalm; + qDebug() << "their left palm:" << otherAvatar->getLeftPalmPosition() + << " their chest:" << otherAvatar->getChestPosition(); }; lastReport = now; From 5ebefadda1e4ffb97dd3459599e41b9c137004ea Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 09:07:35 -0700 Subject: [PATCH 25/33] remove some debugging --- interface/src/Application.cpp | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 733858dd7e..e0e5003830 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2054,42 +2054,11 @@ void Application::checkFPS() { _timerStart.start(); } -uint64_t lastReport = usecTimestampNow(); // XXX - - void Application::idle() { if (_aboutToQuit) { return; // bail early, nothing to do here. } - - // XXX - { // XXX - uint64_t now = usecTimestampNow(); - if (now - lastReport > 6 * USECS_PER_SECOND) { - QSharedPointer avatarManager = DependencyManager::get(); - const AvatarHash& avatarHash = avatarManager->getAvatarHash(); - - qDebug() << "-----------------------"; - - qDebug() << "my left palm:" << getMyAvatar()->getLeftPalmPosition() - << " my chest:" << getMyAvatar()->getChestPosition(); - - QHash::const_iterator i; - for (i = avatarHash.begin(); i != avatarHash.end(); ++i) { - std::shared_ptr otherAvatar = std::static_pointer_cast(i.value()); - if (otherAvatar->getSessionUUID() == getMyAvatar()->getSessionUUID()) { - continue; - } - qDebug() << "their left palm:" << otherAvatar->getLeftPalmPosition() - << " their chest:" << otherAvatar->getChestPosition(); - }; - - lastReport = now; - } - } // XXX - // XXX - // depending on whether we're throttling or not. // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in // perpetuity and not expect events to get backed up. From 9f40c7bf8cedca0a36d3d866f4213217d17e315e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 09:13:06 -0700 Subject: [PATCH 26/33] fix up AvatarActionHold --- interface/src/avatar/AvatarActionHold.cpp | 205 +++++++--------------- 1 file changed, 65 insertions(+), 140 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index f12909e809..22585d962a 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -21,8 +21,7 @@ AvatarActionHold::AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntit ObjectActionSpring(id, ownerEntity), _relativePosition(glm::vec3(0.0f)), _relativeRotation(glm::quat()), - _hand("right"), - _holderID(QUuid()) + _hand("right") { _type = ACTION_TYPE_HOLD; #if WANT_DEBUG @@ -37,122 +36,100 @@ AvatarActionHold::~AvatarActionHold() { } void AvatarActionHold::updateActionWorker(float deltaTimeStep) { - bool gotLock = false; glm::quat rotation; glm::vec3 position; - std::shared_ptr holdingAvatar = nullptr; - - gotLock = withTryReadLock([&]{ - QSharedPointer avatarManager = DependencyManager::get(); - AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID); - holdingAvatar = std::static_pointer_cast(holdingAvatarData); - - if (holdingAvatar) { - glm::vec3 offset; - glm::vec3 palmPosition; - glm::quat palmRotation; - if (_hand == "right") { - palmPosition = holdingAvatar->getRightPalmPosition(); - palmRotation = holdingAvatar->getRightPalmRotation(); - } else { - palmPosition = holdingAvatar->getLeftPalmPosition(); - palmRotation = holdingAvatar->getLeftPalmRotation(); - } - - rotation = palmRotation * _relativeRotation; - offset = rotation * _relativePosition; - position = palmPosition + offset; + glm::vec3 offset; + bool gotLock = withTryReadLock([&]{ + auto myAvatar = DependencyManager::get()->getMyAvatar(); + glm::vec3 palmPosition; + glm::quat palmRotation; + if (_hand == "right") { + palmPosition = myAvatar->getRightPalmPosition(); + palmRotation = myAvatar->getRightPalmRotation(); + } else { + palmPosition = myAvatar->getLeftPalmPosition(); + palmRotation = myAvatar->getLeftPalmRotation(); } + + rotation = palmRotation * _relativeRotation; + offset = rotation * _relativePosition; + position = palmPosition + offset; }); - if (holdingAvatar) { - if (gotLock) { - gotLock = withTryWriteLock([&]{ + if (gotLock) { + gotLock = withTryWriteLock([&]{ + if (_positionalTarget != position || _rotationalTarget != rotation) { + auto ownerEntity = _ownerEntity.lock(); + if (ownerEntity) { + ownerEntity->setActionDataDirty(true); + } _positionalTarget = position; _rotationalTarget = rotation; - }); - } - if (gotLock) { - ObjectActionSpring::updateActionWorker(deltaTimeStep); - } + } + }); + } + + if (gotLock) { + ObjectActionSpring::updateActionWorker(deltaTimeStep); } } bool AvatarActionHold::updateArguments(QVariantMap arguments) { - glm::vec3 relativePosition; - glm::quat relativeRotation; - float timeScale; - QString hand; - QUuid holderID; - bool needUpdate = false; + if (!ObjectAction::updateArguments(arguments)) { + return false; + } + bool ok = true; + glm::vec3 relativePosition = + EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); + if (!ok) { + relativePosition = _relativePosition; + } - bool somethingChanged = ObjectAction::updateArguments(arguments); - withReadLock([&]{ - bool ok = true; - relativePosition = EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); - if (!ok) { - relativePosition = _relativePosition; - } + ok = true; + glm::quat relativeRotation = + EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false); + if (!ok) { + relativeRotation = _relativeRotation; + } + + ok = true; + float timeScale = + EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false); + if (!ok) { + timeScale = _linearTimeScale; + } - ok = true; - relativeRotation = EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false); - if (!ok) { - relativeRotation = _relativeRotation; - } + ok = true; + QString hand = + EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); + if (!ok || !(hand == "left" || hand == "right")) { + hand = _hand; + } - ok = true; - timeScale = EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false); - if (!ok) { - timeScale = _linearTimeScale; - } - - ok = true; - hand = EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); - if (!ok || !(hand == "left" || hand == "right")) { - hand = _hand; - } - - ok = true; - auto myAvatar = DependencyManager::get()->getMyAvatar(); - holderID = myAvatar->getSessionUUID(); - - if (somethingChanged || - relativePosition != _relativePosition + if (relativePosition != _relativePosition || relativeRotation != _relativeRotation || timeScale != _linearTimeScale - || hand != _hand - || holderID != _holderID) { - needUpdate = true; - } - }); - - if (needUpdate) { + || hand != _hand) { withWriteLock([&] { _relativePosition = relativePosition; _relativeRotation = relativeRotation; const float MIN_TIMESCALE = 0.1f; - _linearTimeScale = glm::max(MIN_TIMESCALE, timeScale); + _linearTimeScale = glm::min(MIN_TIMESCALE, timeScale); _angularTimeScale = _linearTimeScale; _hand = hand; - _holderID = holderID; + _active = true; - - auto ownerEntity = _ownerEntity.lock(); - if (ownerEntity) { - ownerEntity->setActionDataDirty(true); - } + activateBody(); }); - activateBody(); } - return true; } + QVariantMap AvatarActionHold::getArguments() { QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&]{ - arguments["holderID"] = _holderID; arguments["relativePosition"] = glmToQMap(_relativePosition); arguments["relativeRotation"] = glmToQMap(_relativeRotation); arguments["timeScale"] = _linearTimeScale; @@ -162,61 +139,9 @@ QVariantMap AvatarActionHold::getArguments() { } QByteArray AvatarActionHold::serialize() const { - QByteArray serializedActionArguments; - QDataStream dataStream(&serializedActionArguments, QIODevice::WriteOnly); - - withReadLock([&]{ - dataStream << ACTION_TYPE_HOLD; - dataStream << getID(); - dataStream << AvatarActionHold::holdVersion; - - dataStream << _holderID; - dataStream << _relativePosition; - dataStream << _relativeRotation; - dataStream << _linearTimeScale; - dataStream << _hand; - - dataStream << _expires; - dataStream << _tag; - }); - - return serializedActionArguments; + return ObjectActionSpring::serialize(); } void AvatarActionHold::deserialize(QByteArray serializedArguments) { - QDataStream dataStream(serializedArguments); - - EntityActionType type; - dataStream >> type; - assert(type == getType()); - - QUuid id; - dataStream >> id; - assert(id == getID()); - - uint16_t serializationVersion; - dataStream >> serializationVersion; - if (serializationVersion != AvatarActionHold::holdVersion) { - return; - } - - withWriteLock([&]{ - dataStream >> _holderID; - dataStream >> _relativePosition; - dataStream >> _relativeRotation; - dataStream >> _linearTimeScale; - _angularTimeScale = _linearTimeScale; - dataStream >> _hand; - - dataStream >> _expires; - dataStream >> _tag; - - #if WANT_DEBUG - qDebug() << "deserialize AvatarActionHold: " << _holderID - << _relativePosition.x << _relativePosition.y << _relativePosition.z - << _hand << _expires; - #endif - - _active = true; - }); + assert(false); } From 7ef5fc9613cf190cb03482b8dad8391b675535ef Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 09:19:47 -0700 Subject: [PATCH 27/33] remove line that leaked over from other branch --- interface/src/avatar/AvatarActionHold.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index 3cc70ced09..2db23e10dc 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -38,7 +38,6 @@ private: glm::vec3 _relativePosition; glm::quat _relativeRotation; QString _hand; - QUuid _holderID; }; #endif // hifi_AvatarActionHold_h From d833fb08d74f365323822f5e0dd8553c42c70b90 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 10:03:32 -0700 Subject: [PATCH 28/33] further unmangle branch split --- interface/src/avatar/AvatarActionHold.cpp | 95 +++++++++++++---------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 22585d962a..1529805e1e 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -36,10 +36,12 @@ AvatarActionHold::~AvatarActionHold() { } void AvatarActionHold::updateActionWorker(float deltaTimeStep) { + bool gotLock = false; glm::quat rotation; glm::vec3 position; glm::vec3 offset; - bool gotLock = withTryReadLock([&]{ + + gotLock = withTryReadLock([&]{ auto myAvatar = DependencyManager::get()->getMyAvatar(); glm::vec3 palmPosition; glm::quat palmRotation; @@ -58,17 +60,10 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { if (gotLock) { gotLock = withTryWriteLock([&]{ - if (_positionalTarget != position || _rotationalTarget != rotation) { - auto ownerEntity = _ownerEntity.lock(); - if (ownerEntity) { - ownerEntity->setActionDataDirty(true); - } _positionalTarget = position; _rotationalTarget = rotation; - } - }); + }); } - if (gotLock) { ObjectActionSpring::updateActionWorker(deltaTimeStep); } @@ -76,57 +71,73 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { bool AvatarActionHold::updateArguments(QVariantMap arguments) { - if (!ObjectAction::updateArguments(arguments)) { - return false; - } - bool ok = true; - glm::vec3 relativePosition = - EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); - if (!ok) { - relativePosition = _relativePosition; - } + glm::vec3 relativePosition; + glm::quat relativeRotation; + float timeScale; + QString hand; + QUuid holderID; + bool needUpdate = false; - ok = true; - glm::quat relativeRotation = - EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false); - if (!ok) { - relativeRotation = _relativeRotation; - } - - ok = true; - float timeScale = - EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false); - if (!ok) { - timeScale = _linearTimeScale; - } + bool somethingChanged = ObjectAction::updateArguments(arguments); + withReadLock([&]{ + bool ok = true; + relativePosition = EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); + if (!ok) { + relativePosition = _relativePosition; + } - ok = true; - QString hand = - EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); - if (!ok || !(hand == "left" || hand == "right")) { - hand = _hand; - } + ok = true; + relativeRotation = EntityActionInterface::extractQuatArgument("hold", arguments, "relativeRotation", ok, false); + if (!ok) { + relativeRotation = _relativeRotation; + } - if (relativePosition != _relativePosition + ok = true; + timeScale = EntityActionInterface::extractFloatArgument("hold", arguments, "timeScale", ok, false); + if (!ok) { + timeScale = _linearTimeScale; + } + + ok = true; + hand = EntityActionInterface::extractStringArgument("hold", arguments, "hand", ok, false); + if (!ok || !(hand == "left" || hand == "right")) { + hand = _hand; + } + + ok = true; + auto myAvatar = DependencyManager::get()->getMyAvatar(); + holderID = myAvatar->getSessionUUID(); + + if (somethingChanged || + relativePosition != _relativePosition || relativeRotation != _relativeRotation || timeScale != _linearTimeScale || hand != _hand) { + needUpdate = true; + } + }); + + if (needUpdate) { withWriteLock([&] { _relativePosition = relativePosition; _relativeRotation = relativeRotation; const float MIN_TIMESCALE = 0.1f; - _linearTimeScale = glm::min(MIN_TIMESCALE, timeScale); + _linearTimeScale = glm::max(MIN_TIMESCALE, timeScale); _angularTimeScale = _linearTimeScale; _hand = hand; - _active = true; - activateBody(); + + auto ownerEntity = _ownerEntity.lock(); + if (ownerEntity) { + ownerEntity->setActionDataDirty(true); + } }); + activateBody(); } + return true; } - QVariantMap AvatarActionHold::getArguments() { QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&]{ From 8195145dc787b952d3230f82f9b154b30b42d968 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 10:13:00 -0700 Subject: [PATCH 29/33] further unmangle branch split --- interface/src/avatar/AvatarActionHold.cpp | 8 ++++---- interface/src/avatar/AvatarActionHold.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 1529805e1e..51394798ab 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -109,10 +109,10 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { holderID = myAvatar->getSessionUUID(); if (somethingChanged || - relativePosition != _relativePosition - || relativeRotation != _relativeRotation - || timeScale != _linearTimeScale - || hand != _hand) { + relativePosition != _relativePosition || + relativeRotation != _relativeRotation || + timeScale != _linearTimeScale || + hand != _hand) { needUpdate = true; } }); diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index 2db23e10dc..840ba41c28 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -30,7 +30,7 @@ public: QByteArray serialize() const; virtual void deserialize(QByteArray serializedArguments); - virtual bool shouldSuppressLocationEdits() { return true; } + virtual bool shouldSuppressLocationEdits() { return false; } private: static const uint16_t holdVersion; From e571cb7ca44384121fc48e7868a411198ec770a3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 10:22:25 -0700 Subject: [PATCH 30/33] more lock adjustments --- libraries/physics/src/ObjectActionOffset.cpp | 35 ++++++++--------- libraries/physics/src/ObjectActionSpring.cpp | 40 ++++++++++---------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index 4930d44f3c..d01178dcc3 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -151,17 +151,18 @@ QVariantMap ObjectActionOffset::getArguments() { QByteArray ObjectActionOffset::serialize() const { QByteArray ba; QDataStream dataStream(&ba, QIODevice::WriteOnly); - dataStream << getType(); + dataStream << ACTION_TYPE_OFFSET; dataStream << getID(); dataStream << ObjectActionOffset::offsetVersion; - dataStream << _pointToOffsetFrom; - dataStream << _linearDistance; - dataStream << _linearTimeScale; - dataStream << _positionalTargetSet; - - dataStream << _expires; - dataStream << _tag; + withReadLock([&] { + dataStream << _pointToOffsetFrom; + dataStream << _linearDistance; + dataStream << _linearTimeScale; + dataStream << _positionalTargetSet; + dataStream << _expires; + dataStream << _tag; + }); return ba; } @@ -183,13 +184,13 @@ void ObjectActionOffset::deserialize(QByteArray serializedArguments) { return; } - dataStream >> _pointToOffsetFrom; - dataStream >> _linearDistance; - dataStream >> _linearTimeScale; - dataStream >> _positionalTargetSet; - - dataStream >> _expires; - dataStream >> _tag; - - _active = true; + withWriteLock([&] { + dataStream >> _pointToOffsetFrom; + dataStream >> _linearDistance; + dataStream >> _linearTimeScale; + dataStream >> _positionalTargetSet; + dataStream >> _expires; + dataStream >> _tag; + _active = true; + }); } diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index 242849db6f..38b4b71d26 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -191,16 +191,16 @@ QByteArray ObjectActionSpring::serialize() const { dataStream << getID(); dataStream << ObjectActionSpring::springVersion; - dataStream << _positionalTarget; - dataStream << _linearTimeScale; - dataStream << _positionalTargetSet; - - dataStream << _rotationalTarget; - dataStream << _angularTimeScale; - dataStream << _rotationalTargetSet; - - dataStream << _expires; - dataStream << _tag; + withReadLock([&] { + dataStream << _positionalTarget; + dataStream << _linearTimeScale; + dataStream << _positionalTargetSet; + dataStream << _rotationalTarget; + dataStream << _angularTimeScale; + dataStream << _rotationalTargetSet; + dataStream << _expires; + dataStream << _tag; + }); return serializedActionArguments; } @@ -222,16 +222,18 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { return; } - dataStream >> _positionalTarget; - dataStream >> _linearTimeScale; - dataStream >> _positionalTargetSet; + withWriteLock([&] { + dataStream >> _positionalTarget; + dataStream >> _linearTimeScale; + dataStream >> _positionalTargetSet; - dataStream >> _rotationalTarget; - dataStream >> _angularTimeScale; - dataStream >> _rotationalTargetSet; + dataStream >> _rotationalTarget; + dataStream >> _angularTimeScale; + dataStream >> _rotationalTargetSet; - dataStream >> _expires; - dataStream >> _tag; + dataStream >> _expires; + dataStream >> _tag; - _active = true; + _active = true; + }); } From a78728c96b0f447f9a13e74df3ae6101c8096d2e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 10:29:25 -0700 Subject: [PATCH 31/33] further unmangle branch split --- interface/src/avatar/AvatarActionHold.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 51394798ab..4288a354f5 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -60,9 +60,11 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { if (gotLock) { gotLock = withTryWriteLock([&]{ - _positionalTarget = position; - _rotationalTarget = rotation; - }); + _positionalTarget = position; + _rotationalTarget = rotation; + _positionalTargetSet = true; + _rotationalTargetSet = true; + }); } if (gotLock) { ObjectActionSpring::updateActionWorker(deltaTimeStep); From 64c5cde2d2aee33acc43a8487401cc6dc44d9204 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 10:33:58 -0700 Subject: [PATCH 32/33] further unmangle branch split --- interface/src/avatar/AvatarActionHold.cpp | 4 ++++ libraries/physics/src/ObjectActionSpring.cpp | 1 + 2 files changed, 5 insertions(+) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 4288a354f5..3c57db084b 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -64,6 +64,10 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { _rotationalTarget = rotation; _positionalTargetSet = true; _rotationalTargetSet = true; + auto ownerEntity = _ownerEntity.lock(); + if (ownerEntity) { + ownerEntity->setActionDataDirty(true); + } }); } if (gotLock) { diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index 38b4b71d26..a99cfdd747 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -219,6 +219,7 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { uint16_t serializationVersion; dataStream >> serializationVersion; if (serializationVersion != ObjectActionSpring::springVersion) { + assert(false); return; } From c884f466bc3d7977abc977f09522d4a3d91689b7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 10:40:58 -0700 Subject: [PATCH 33/33] adjust timing of action refresh --- examples/controllers/handControllerGrab.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index ee16eadeed..117ee8c453 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -66,7 +66,8 @@ var MSEC_PER_SEC = 1000.0; // these control how long an abandoned pointer line will hang around var startTime = Date.now(); var LIFETIME = 10; -var ACTION_LIFETIME = 10; // seconds +var ACTION_LIFETIME = 15; // seconds +var ACTION_LIFETIME_REFRESH = 5; var PICKS_PER_SECOND_PER_HAND = 5; var MSECS_PER_SEC = 1000.0; @@ -536,8 +537,8 @@ function MyController(hand, triggerAction) { this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); - if (this.actionTimeout - now < MSEC_PER_SEC) { - // if less than a second left, refresh the actions lifetime + if (this.actionTimeout - now < ACTION_LIFETIME_REFRESH * MSEC_PER_SEC) { + // if less than a 5 seconds left, refresh the actions lifetime Entities.updateAction(this.grabbedEntity, this.actionID, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME,