Merge pull request #6390 from sethalves/average-near-holds

Average near holds
This commit is contained in:
Philip Rosedale 2015-11-17 20:01:46 -08:00
commit 450608bf5b
7 changed files with 85 additions and 30 deletions

View file

@ -10,7 +10,6 @@
// //
#include "QVariantGLM.h" #include "QVariantGLM.h"
#include "avatar/MyAvatar.h"
#include "avatar/AvatarManager.h" #include "avatar/AvatarManager.h"
#include "AvatarActionHold.h" #include "AvatarActionHold.h"
@ -22,8 +21,7 @@ AvatarActionHold::AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntit
_relativePosition(glm::vec3(0.0f)), _relativePosition(glm::vec3(0.0f)),
_relativeRotation(glm::quat()), _relativeRotation(glm::quat()),
_hand("right"), _hand("right"),
_holderID(QUuid()) _holderID(QUuid()) {
{
_type = ACTION_TYPE_HOLD; _type = ACTION_TYPE_HOLD;
#if WANT_DEBUG #if WANT_DEBUG
qDebug() << "AvatarActionHold::AvatarActionHold"; qDebug() << "AvatarActionHold::AvatarActionHold";
@ -36,13 +34,10 @@ AvatarActionHold::~AvatarActionHold() {
#endif #endif
} }
void AvatarActionHold::updateActionWorker(float deltaTimeStep) { std::shared_ptr<Avatar> AvatarActionHold::getTarget(glm::quat& rotation, glm::vec3& position) {
bool gotLock = false;
glm::quat rotation;
glm::vec3 position;
std::shared_ptr<Avatar> holdingAvatar = nullptr; std::shared_ptr<Avatar> holdingAvatar = nullptr;
gotLock = withTryReadLock([&]{ withTryReadLock([&]{
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>(); QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID); AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID);
holdingAvatar = std::static_pointer_cast<Avatar>(holdingAvatarData); holdingAvatar = std::static_pointer_cast<Avatar>(holdingAvatarData);
@ -65,22 +60,53 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
} }
}); });
if (holdingAvatar) { return holdingAvatar;
}
void AvatarActionHold::updateActionWorker(float deltaTimeStep) {
glm::quat rotation;
glm::vec3 position;
bool valid = false;
int holdCount = 0;
auto ownerEntity = _ownerEntity.lock();
if (!ownerEntity) {
return;
}
QList<EntityActionPointer> holdActions = ownerEntity->getActionsOfType(ACTION_TYPE_HOLD);
foreach (EntityActionPointer action, holdActions) {
std::shared_ptr<AvatarActionHold> holdAction = std::static_pointer_cast<AvatarActionHold>(action);
glm::quat rotationForAction;
glm::vec3 positionForAction;
std::shared_ptr<Avatar> 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;
bool gotLock = withTryWriteLock([&]{
_positionalTarget = position;
_rotationalTarget = rotation;
_positionalTargetSet = true;
_rotationalTargetSet = true;
_active = true;
});
if (gotLock) { if (gotLock) {
gotLock = withTryWriteLock([&]{ if (_kinematic) {
_positionalTarget = position; doKinematicUpdate(deltaTimeStep);
_rotationalTarget = rotation; } else {
_positionalTargetSet = true; activateBody();
_rotationalTargetSet = true; ObjectActionSpring::updateActionWorker(deltaTimeStep);
_active = true;
});
if (gotLock) {
if (_kinematic) {
doKinematicUpdate(deltaTimeStep);
} else {
activateBody();
ObjectActionSpring::updateActionWorker(deltaTimeStep);
}
} }
} }
} }
@ -109,7 +135,8 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
if (_previousSet) { if (_previousSet) {
// smooth velocity over 2 frames // smooth velocity over 2 frames
glm::vec3 positionalDelta = _positionalTarget - _previousPositionalTarget; glm::vec3 positionalDelta = _positionalTarget - _previousPositionalTarget;
glm::vec3 positionalVelocity = (positionalDelta + _previousPositionalDelta) / (deltaTimeStep + _previousDeltaTimeStep); glm::vec3 positionalVelocity =
(positionalDelta + _previousPositionalDelta) / (deltaTimeStep + _previousDeltaTimeStep);
rigidBody->setLinearVelocity(glmToBullet(positionalVelocity)); rigidBody->setLinearVelocity(glmToBullet(positionalVelocity));
_previousPositionalDelta = positionalDelta; _previousPositionalDelta = positionalDelta;
_previousDeltaTimeStep = deltaTimeStep; _previousDeltaTimeStep = deltaTimeStep;

View file

@ -17,6 +17,9 @@
#include <EntityItem.h> #include <EntityItem.h>
#include <ObjectActionSpring.h> #include <ObjectActionSpring.h>
#include "avatar/MyAvatar.h"
class AvatarActionHold : public ObjectActionSpring { class AvatarActionHold : public ObjectActionSpring {
public: public:
AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntity); AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntity);
@ -32,6 +35,8 @@ public:
virtual bool shouldSuppressLocationEdits() { return _active && !_ownerEntity.expired(); } virtual bool shouldSuppressLocationEdits() { return _active && !_ownerEntity.expired(); }
std::shared_ptr<Avatar> getTarget(glm::quat& rotation, glm::vec3& position);
private: private:
static const uint16_t holdVersion; static const uint16_t holdVersion;

View file

@ -12,11 +12,14 @@
#ifndef hifi_EntityActionInterface_h #ifndef hifi_EntityActionInterface_h
#define hifi_EntityActionInterface_h #define hifi_EntityActionInterface_h
#include <memory>
#include <QUuid> #include <QUuid>
#include <glm/glm.hpp>
#include "EntityItem.h" class EntityItem;
class EntitySimulation; class EntitySimulation;
using EntityItemPointer = std::shared_ptr<EntityItem>;
using EntityItemWeakPointer = std::weak_ptr<EntityItem>;
enum EntityActionType { enum EntityActionType {
// keep these synchronized with actionTypeFromString and actionTypeToString // keep these synchronized with actionTypeFromString and actionTypeToString
@ -34,6 +37,8 @@ public:
const QUuid& getID() const { return _id; } const QUuid& getID() const { return _id; }
EntityActionType getType() const { return _type; } EntityActionType getType() const { return _type; }
bool isActive() { return _active; }
virtual void removeFromSimulation(EntitySimulation* simulation) const = 0; virtual void removeFromSimulation(EntitySimulation* simulation) const = 0;
virtual EntityItemWeakPointer getOwnerEntity() const = 0; virtual EntityItemWeakPointer getOwnerEntity() const = 0;
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) = 0; virtual void setOwnerEntity(const EntityItemPointer ownerEntity) = 0;
@ -81,6 +86,7 @@ protected:
QUuid _id; QUuid _id;
EntityActionType _type; EntityActionType _type;
bool _active { false };
}; };

View file

@ -1844,3 +1844,18 @@ bool EntityItem::shouldSuppressLocationEdits() const {
return false; return false;
} }
QList<EntityActionPointer> EntityItem::getActionsOfType(EntityActionType typeToGet) {
QList<EntityActionPointer> result;
QHash<QUuid, EntityActionPointer>::const_iterator i = _objectActions.begin();
while (i != _objectActions.end()) {
EntityActionPointer action = i.value();
if (action->getType() == typeToGet && action->isActive()) {
result += action;
}
i++;
}
return result;
}

View file

@ -30,6 +30,7 @@
#include "EntityTypes.h" #include "EntityTypes.h"
#include "SimulationOwner.h" #include "SimulationOwner.h"
#include "SimulationFlags.h" #include "SimulationFlags.h"
#include "EntityActionInterface.h"
class EntitySimulation; class EntitySimulation;
class EntityTreeElement; class EntityTreeElement;
@ -419,7 +420,9 @@ public:
void setSourceUUID(const QUuid& sourceUUID) { _sourceUUID = sourceUUID; } void setSourceUUID(const QUuid& sourceUUID) { _sourceUUID = sourceUUID; }
const QUuid& getSourceUUID() const { return _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<EntityActionPointer> getActionsOfType(EntityActionType typeToGet);
protected: protected:

View file

@ -20,8 +20,8 @@
#include <OctreeRenderer.h> // for RenderArgs #include <OctreeRenderer.h> // for RenderArgs
class EntityItem; class EntityItem;
typedef std::shared_ptr<EntityItem> EntityItemPointer; using EntityItemPointer = std::shared_ptr<EntityItem>;
typedef std::weak_ptr<EntityItem> EntityItemWeakPointer; using EntityItemWeakPointer = std::weak_ptr<EntityItem>;
inline uint qHash(const EntityItemPointer& a, uint seed) { inline uint qHash(const EntityItemPointer& a, uint seed) {
return qHash(a.get(), seed); return qHash(a.get(), seed);

View file

@ -67,7 +67,6 @@ protected:
EntityItemWeakPointer _ownerEntity; EntityItemWeakPointer _ownerEntity;
QString _tag; QString _tag;
quint64 _expires { 0 }; // in seconds since epoch quint64 _expires { 0 }; // in seconds since epoch
bool _active { false };
private: private:
int getEntityServerClockSkew() const; int getEntityServerClockSkew() const;