From ac635336b79ae5e77df76b1c86ab3e3d2970fa89 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Nov 2015 14:58:17 -0800 Subject: [PATCH 1/2] split AvatarActionHold's finding of its location target into a new function --- interface/src/avatar/AvatarActionHold.cpp | 48 ++++++++++++----------- interface/src/avatar/AvatarActionHold.h | 5 +++ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 839f2d4fbb..ca7fcfb187 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -10,7 +10,6 @@ // #include "QVariantGLM.h" -#include "avatar/MyAvatar.h" #include "avatar/AvatarManager.h" #include "AvatarActionHold.h" @@ -22,8 +21,7 @@ AvatarActionHold::AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntit _relativePosition(glm::vec3(0.0f)), _relativeRotation(glm::quat()), _hand("right"), - _holderID(QUuid()) -{ + _holderID(QUuid()) { _type = ACTION_TYPE_HOLD; #if WANT_DEBUG qDebug() << "AvatarActionHold::AvatarActionHold"; @@ -36,13 +34,10 @@ AvatarActionHold::~AvatarActionHold() { #endif } -void AvatarActionHold::updateActionWorker(float deltaTimeStep) { - bool gotLock = false; - glm::quat rotation; - glm::vec3 position; +std::shared_ptr AvatarActionHold::getTarget(glm::quat& rotation, glm::vec3& position) { std::shared_ptr holdingAvatar = nullptr; - gotLock = withTryReadLock([&]{ + withTryReadLock([&]{ QSharedPointer avatarManager = DependencyManager::get(); AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID); holdingAvatar = std::static_pointer_cast(holdingAvatarData); @@ -65,22 +60,28 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { } }); + return holdingAvatar; +} + +void AvatarActionHold::updateActionWorker(float deltaTimeStep) { + glm::quat rotation; + glm::vec3 position; + std::shared_ptr holdingAvatar = getTarget(rotation, position); + if (holdingAvatar) { + bool gotLock = withTryWriteLock([&]{ + _positionalTarget = position; + _rotationalTarget = rotation; + _positionalTargetSet = true; + _rotationalTargetSet = true; + _active = true; + }); if (gotLock) { - gotLock = withTryWriteLock([&]{ - _positionalTarget = position; - _rotationalTarget = rotation; - _positionalTargetSet = true; - _rotationalTargetSet = true; - _active = true; - }); - if (gotLock) { - if (_kinematic) { - doKinematicUpdate(deltaTimeStep); - } else { - activateBody(); - ObjectActionSpring::updateActionWorker(deltaTimeStep); - } + if (_kinematic) { + doKinematicUpdate(deltaTimeStep); + } else { + activateBody(); + ObjectActionSpring::updateActionWorker(deltaTimeStep); } } } @@ -109,7 +110,8 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { if (_previousSet) { // smooth velocity over 2 frames glm::vec3 positionalDelta = _positionalTarget - _previousPositionalTarget; - glm::vec3 positionalVelocity = (positionalDelta + _previousPositionalDelta) / (deltaTimeStep + _previousDeltaTimeStep); + glm::vec3 positionalVelocity = + (positionalDelta + _previousPositionalDelta) / (deltaTimeStep + _previousDeltaTimeStep); rigidBody->setLinearVelocity(glmToBullet(positionalVelocity)); _previousPositionalDelta = positionalDelta; _previousDeltaTimeStep = deltaTimeStep; diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index 15a096d1ce..b8b1a64e84 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -17,6 +17,9 @@ #include #include +#include "avatar/MyAvatar.h" + + class AvatarActionHold : public ObjectActionSpring { public: AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntity); @@ -32,6 +35,8 @@ public: virtual bool shouldSuppressLocationEdits() { return _active && !_ownerEntity.expired(); } + std::shared_ptr getTarget(glm::quat& rotation, glm::vec3& position); + private: static const uint16_t holdVersion; From b0d24be58fc854da97ee94625a6dad2dc864b5ed Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Nov 2015 16:02:39 -0800 Subject: [PATCH 2/2] add a way to get a list of all actions of a certain type from an entity. hold actions average their positional targets. --- interface/src/avatar/AvatarActionHold.cpp | 29 +++++++++++++++++-- .../entities/src/EntityActionInterface.h | 10 +++++-- libraries/entities/src/EntityItem.cpp | 15 ++++++++++ libraries/entities/src/EntityItem.h | 5 +++- libraries/entities/src/EntityTypes.h | 4 +-- libraries/physics/src/ObjectAction.h | 1 - 6 files changed, 56 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index ca7fcfb187..8e13fa8385 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -66,9 +66,34 @@ std::shared_ptr AvatarActionHold::getTarget(glm::quat& rotation, glm::ve void AvatarActionHold::updateActionWorker(float deltaTimeStep) { glm::quat rotation; glm::vec3 position; - std::shared_ptr holdingAvatar = getTarget(rotation, position); + bool valid = false; + int holdCount = 0; + + auto ownerEntity = _ownerEntity.lock(); + if (!ownerEntity) { + return; + } + QList holdActions = ownerEntity->getActionsOfType(ACTION_TYPE_HOLD); + foreach (EntityActionPointer action, holdActions) { + std::shared_ptr holdAction = std::static_pointer_cast(action); + glm::quat rotationForAction; + glm::vec3 positionForAction; + std::shared_ptr holdingAvatar = holdAction->getTarget(rotationForAction, positionForAction); + if (holdingAvatar) { + holdCount ++; + if (holdAction.get() == this) { + // only use the rotation for this action + valid = true; + rotation = rotationForAction; + } + + position += positionForAction; + } + } + + if (valid && holdCount > 0) { + position /= holdCount; - if (holdingAvatar) { bool gotLock = withTryWriteLock([&]{ _positionalTarget = position; _rotationalTarget = rotation; diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index 01292e3840..a192661e52 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -12,11 +12,14 @@ #ifndef hifi_EntityActionInterface_h #define hifi_EntityActionInterface_h +#include #include +#include -#include "EntityItem.h" - +class EntityItem; class EntitySimulation; +using EntityItemPointer = std::shared_ptr; +using EntityItemWeakPointer = std::weak_ptr; enum EntityActionType { // keep these synchronized with actionTypeFromString and actionTypeToString @@ -34,6 +37,8 @@ public: const QUuid& getID() const { return _id; } EntityActionType getType() const { return _type; } + bool isActive() { return _active; } + virtual void removeFromSimulation(EntitySimulation* simulation) const = 0; virtual EntityItemWeakPointer getOwnerEntity() const = 0; virtual void setOwnerEntity(const EntityItemPointer ownerEntity) = 0; @@ -81,6 +86,7 @@ protected: QUuid _id; EntityActionType _type; + bool _active { false }; }; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f032dcd347..100f6dfe22 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1844,3 +1844,18 @@ bool EntityItem::shouldSuppressLocationEdits() const { return false; } + +QList EntityItem::getActionsOfType(EntityActionType typeToGet) { + QList result; + + QHash::const_iterator i = _objectActions.begin(); + while (i != _objectActions.end()) { + EntityActionPointer action = i.value(); + if (action->getType() == typeToGet && action->isActive()) { + result += action; + } + i++; + } + + return result; +} diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 5b47198e97..5ceccef4b1 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -30,6 +30,7 @@ #include "EntityTypes.h" #include "SimulationOwner.h" #include "SimulationFlags.h" +#include "EntityActionInterface.h" class EntitySimulation; class EntityTreeElement; @@ -419,7 +420,9 @@ public: void setSourceUUID(const QUuid& sourceUUID) { _sourceUUID = sourceUUID; } const QUuid& getSourceUUID() const { return _sourceUUID; } - bool matchesSourceUUID(const QUuid& sourceUUID) const { return _sourceUUID == sourceUUID; } + bool matchesSourceUUID(const QUuid& sourceUUID) const { return _sourceUUID == sourceUUID; } + + QList getActionsOfType(EntityActionType typeToGet); protected: diff --git a/libraries/entities/src/EntityTypes.h b/libraries/entities/src/EntityTypes.h index 30b6edbc07..3536327d18 100644 --- a/libraries/entities/src/EntityTypes.h +++ b/libraries/entities/src/EntityTypes.h @@ -20,8 +20,8 @@ #include // for RenderArgs class EntityItem; -typedef std::shared_ptr EntityItemPointer; -typedef std::weak_ptr EntityItemWeakPointer; +using EntityItemPointer = std::shared_ptr; +using EntityItemWeakPointer = std::weak_ptr; inline uint qHash(const EntityItemPointer& a, uint seed) { return qHash(a.get(), seed); diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 45b40a9fb3..afb6745e9c 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -67,7 +67,6 @@ protected: EntityItemWeakPointer _ownerEntity; QString _tag; quint64 _expires { 0 }; // in seconds since epoch - bool _active { false }; private: int getEntityServerClockSkew() const;