From 85564199c67c36b92efd6b5d7ae8f8803d45953b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 17 Jun 2015 11:22:10 -0700 Subject: [PATCH] git rid if pull-to-point action (spring handles this). add new action which tries to maintain an entity's distance from a given point --- interface/src/InterfaceActionFactory.cpp | 6 +- interface/src/avatar/AvatarActionHold.cpp | 11 +- .../entities/src/EntityActionInterface.cpp | 8 +- .../entities/src/EntityActionInterface.h | 2 +- libraries/physics/src/ObjectAction.cpp | 2 +- libraries/physics/src/ObjectAction.h | 1 + libraries/physics/src/ObjectActionOffset.cpp | 109 ++++++++++++++++++ libraries/physics/src/ObjectActionOffset.h | 35 ++++++ .../physics/src/ObjectActionPullToPoint.cpp | 72 ------------ .../physics/src/ObjectActionPullToPoint.h | 34 ------ 10 files changed, 164 insertions(+), 116 deletions(-) create mode 100644 libraries/physics/src/ObjectActionOffset.cpp create mode 100644 libraries/physics/src/ObjectActionOffset.h delete mode 100644 libraries/physics/src/ObjectActionPullToPoint.cpp delete mode 100644 libraries/physics/src/ObjectActionPullToPoint.h diff --git a/interface/src/InterfaceActionFactory.cpp b/interface/src/InterfaceActionFactory.cpp index 08afc3581c..dfc22c5e7d 100644 --- a/interface/src/InterfaceActionFactory.cpp +++ b/interface/src/InterfaceActionFactory.cpp @@ -12,7 +12,7 @@ #include -#include +#include #include #include "InterfaceActionFactory.h" @@ -27,8 +27,8 @@ EntityActionPointer InterfaceActionFactory::factory(EntitySimulation* simulation switch (type) { case ACTION_TYPE_NONE: return nullptr; - case ACTION_TYPE_PULL_TO_POINT: - action = (EntityActionPointer) new ObjectActionPullToPoint(id, ownerEntity); + case ACTION_TYPE_OFFSET: + action = (EntityActionPointer) new ObjectActionOffset(id, ownerEntity); break; case ACTION_TYPE_SPRING: action = (EntityActionPointer) new ObjectActionSpring(id, ownerEntity); diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 1fbb01beb3..24ed9ba0e2 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -29,6 +29,12 @@ AvatarActionHold::~AvatarActionHold() { void AvatarActionHold::updateActionWorker(float deltaTimeStep) { auto myAvatar = DependencyManager::get()->getMyAvatar(); + + if (!tryLockForRead()) { + // don't risk hanging the thread running the physics simulation + return; + } + glm::vec3 palmPosition; if (_hand == "right") { palmPosition = myAvatar->getRightPalmPosition(); @@ -40,8 +46,11 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { auto offset = rotation * _relativePosition; auto position = palmPosition + offset; rotation *= _relativeRotation; + unlock(); - lockForWrite(); + if (!tryLockForWrite()) { + return; + } _positionalTarget = position; _rotationalTarget = rotation; unlock(); diff --git a/libraries/entities/src/EntityActionInterface.cpp b/libraries/entities/src/EntityActionInterface.cpp index e97669686c..54abdc4454 100644 --- a/libraries/entities/src/EntityActionInterface.cpp +++ b/libraries/entities/src/EntityActionInterface.cpp @@ -19,8 +19,8 @@ EntityActionType EntityActionInterface::actionTypeFromString(QString actionTypeS if (normalizedActionTypeString == "none") { return ACTION_TYPE_NONE; } - if (normalizedActionTypeString == "pulltopoint") { - return ACTION_TYPE_PULL_TO_POINT; + if (normalizedActionTypeString == "offset") { + return ACTION_TYPE_OFFSET; } if (normalizedActionTypeString == "spring") { return ACTION_TYPE_SPRING; @@ -37,8 +37,8 @@ QString EntityActionInterface::actionTypeToString(EntityActionType actionType) { switch(actionType) { case ACTION_TYPE_NONE: return "none"; - case ACTION_TYPE_PULL_TO_POINT: - return "pullToPoint"; + case ACTION_TYPE_OFFSET: + return "offset"; case ACTION_TYPE_SPRING: return "spring"; case ACTION_TYPE_HOLD: diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index 486d3f5948..bd7a3217d5 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -21,7 +21,7 @@ class EntitySimulation; enum EntityActionType { // keep these synchronized with actionTypeFromString and actionTypeToString ACTION_TYPE_NONE, - ACTION_TYPE_PULL_TO_POINT, + ACTION_TYPE_OFFSET, ACTION_TYPE_SPRING, ACTION_TYPE_HOLD }; diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index ee7ba9ce7c..3759d04d80 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -28,7 +28,7 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta return; } if (!_ownerEntity) { - qDebug() << "ObjectActionPullToPoint::updateAction no owner entity"; + qDebug() << "ObjectAction::updateAction no owner entity"; return; } updateActionWorker(deltaTimeStep); diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 0fd7383e6f..f15a0ba872 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -59,6 +59,7 @@ protected: bool tryLockForRead() { return _lock.tryLockForRead(); } void lockForWrite() { _lock.lockForWrite(); } + bool tryLockForWrite() { return _lock.tryLockForWrite(); } void unlock() { _lock.unlock(); } bool _active; diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp new file mode 100644 index 0000000000..1db43d1432 --- /dev/null +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -0,0 +1,109 @@ +// +// ObjectActionOffset.cpp +// libraries/physics/src +// +// Created by Seth Alves 2015-6-17 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ObjectActionOffset.h" + +ObjectActionOffset::ObjectActionOffset(QUuid id, EntityItemPointer ownerEntity) : + ObjectAction(id, ownerEntity) { + #if WANT_DEBUG + qDebug() << "ObjectActionOffset::ObjectActionOffset"; + #endif +} + +ObjectActionOffset::~ObjectActionOffset() { + #if WANT_DEBUG + qDebug() << "ObjectActionOffset::~ObjectActionOffset"; + #endif +} + +void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) { + if (!tryLockForRead()) { + // don't risk hanging the thread running the physics simulation + return; + } + + void* physicsInfo = _ownerEntity->getPhysicsInfo(); + if (!physicsInfo) { + unlock(); + return; + } + ObjectMotionState* motionState = static_cast(physicsInfo); + btRigidBody* rigidBody = motionState->getRigidBody(); + if (!rigidBody) { + unlock(); + qDebug() << "ObjectActionOffset::updateActionWorker no rigidBody"; + return; + } + + if (_positionalTargetSet) { + glm::vec3 offset = _pointToOffsetFrom - bulletToGLM(rigidBody->getCenterOfMassPosition()); + float offsetLength = glm::length(offset); + float offsetError = _linearDistance - offsetLength; + + // if (glm::abs(offsetError) > IGNORE_POSITION_DELTA) { + if (glm::abs(offsetError) > 0.0f) { + float offsetErrorAbs = glm::abs(offsetError); + float offsetErrorDirection = - offsetError / offsetErrorAbs; + glm::vec3 previousVelocity = bulletToGLM(rigidBody->getLinearVelocity()); + + glm::vec3 velocityAdjustment = glm::normalize(offset) * offsetErrorDirection * offsetErrorAbs / _linearTimeScale; + rigidBody->setLinearVelocity(glmToBullet(previousVelocity + velocityAdjustment)); + // rigidBody->setLinearVelocity(glmToBullet(velocityAdjustment)); + rigidBody->activate(); + } + } + + unlock(); +} + + +bool ObjectActionOffset::updateArguments(QVariantMap arguments) { + bool pOk0 = true; + glm::vec3 pointToOffsetFrom = + EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", pOk0, true); + + bool pOk1 = true; + float linearTimeScale = + EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", pOk1, false); + + bool pOk2 = true; + float linearDistance = + EntityActionInterface::extractFloatArgument("offset action", arguments, "linearDistance", pOk2, false); + + if (!pOk0) { + return false; + } + if (pOk1 && linearTimeScale <= 0.0f) { + qDebug() << "offset action -- linearTimeScale must be greater than zero."; + return false; + } + + lockForWrite(); + + _pointToOffsetFrom = pointToOffsetFrom; + _positionalTargetSet = true; + + if (pOk1) { + _linearTimeScale = linearTimeScale; + } else { + _linearTimeScale = 0.1f; + } + + if (pOk2) { + _linearDistance = linearDistance; + } else { + _linearDistance = 1.0f; + } + + _active = true; + unlock(); + return true; +} diff --git a/libraries/physics/src/ObjectActionOffset.h b/libraries/physics/src/ObjectActionOffset.h new file mode 100644 index 0000000000..874b0a5477 --- /dev/null +++ b/libraries/physics/src/ObjectActionOffset.h @@ -0,0 +1,35 @@ +// +// ObjectActionOffset.h +// libraries/physics/src +// +// Created by Seth Alves 2015-6-17 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ObjectActionOffset_h +#define hifi_ObjectActionOffset_h + +#include + +#include +#include "ObjectAction.h" + +class ObjectActionOffset : public ObjectAction { +public: + ObjectActionOffset(QUuid id, EntityItemPointer ownerEntity); + virtual ~ObjectActionOffset(); + + virtual bool updateArguments(QVariantMap arguments); + virtual void updateActionWorker(float deltaTimeStep); + +private: + glm::vec3 _pointToOffsetFrom; + float _linearDistance; + float _linearTimeScale; + bool _positionalTargetSet; +}; + +#endif // hifi_ObjectActionOffset_h diff --git a/libraries/physics/src/ObjectActionPullToPoint.cpp b/libraries/physics/src/ObjectActionPullToPoint.cpp deleted file mode 100644 index 053bef6a03..0000000000 --- a/libraries/physics/src/ObjectActionPullToPoint.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// -// ObjectActionPullToPoint.cpp -// libraries/physics/src -// -// Created by Seth Alves 2015-6-2 -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "ObjectActionPullToPoint.h" - -ObjectActionPullToPoint::ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity) : - ObjectAction(id, ownerEntity) { - #if WANT_DEBUG - qDebug() << "ObjectActionPullToPoint::ObjectActionPullToPoint"; - #endif -} - -ObjectActionPullToPoint::~ObjectActionPullToPoint() { - #if WANT_DEBUG - qDebug() << "ObjectActionPullToPoint::~ObjectActionPullToPoint"; - #endif -} - -void ObjectActionPullToPoint::updateActionWorker(btScalar deltaTimeStep) { - if (!tryLockForRead()) { - // don't risk hanging the thread running the physics simulation - return; - } - - void* physicsInfo = _ownerEntity->getPhysicsInfo(); - if (!physicsInfo) { - unlock(); - return; - } - ObjectMotionState* motionState = static_cast(physicsInfo); - btRigidBody* rigidBody = motionState->getRigidBody(); - if (!rigidBody) { - unlock(); - return; - } - - glm::vec3 offset = _target - bulletToGLM(rigidBody->getCenterOfMassPosition()); - float offsetLength = glm::length(offset); - if (offsetLength > IGNORE_POSITION_DELTA) { - glm::vec3 newVelocity = glm::normalize(offset) * _speed; - rigidBody->setLinearVelocity(glmToBullet(newVelocity)); - rigidBody->activate(); - } else { - rigidBody->setLinearVelocity(glmToBullet(glm::vec3())); - } - - unlock(); -} - - -bool ObjectActionPullToPoint::updateArguments(QVariantMap arguments) { - bool ok = true; - glm::vec3 target = EntityActionInterface::extractVec3Argument("pull-to-point action", arguments, "target", ok); - float speed = EntityActionInterface::extractFloatArgument("pull-to-point action", arguments, "speed", ok); - if (ok) { - lockForWrite(); - _target = target; - _speed = speed; - _active = true; - unlock(); - return true; - } - return false; -} diff --git a/libraries/physics/src/ObjectActionPullToPoint.h b/libraries/physics/src/ObjectActionPullToPoint.h deleted file mode 100644 index 2596f13515..0000000000 --- a/libraries/physics/src/ObjectActionPullToPoint.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// ObjectActionPullToPoint.h -// libraries/physics/src -// -// Created by Seth Alves 2015-6-3 -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_ObjectActionPullToPoint_h -#define hifi_ObjectActionPullToPoint_h - -#include - -#include -#include "ObjectAction.h" - -class ObjectActionPullToPoint : public ObjectAction { -public: - ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity); - virtual ~ObjectActionPullToPoint(); - - virtual bool updateArguments(QVariantMap arguments); - virtual void updateActionWorker(float deltaTimeStep); - -private: - - glm::vec3 _target; - float _speed; -}; - -#endif // hifi_ObjectActionPullToPoint_h