From 359a318568f4fb8acc9777a901bc0cdf7c2b3dc3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 20:23:06 -0700 Subject: [PATCH] fold kinematic hold into normal hold (disabled by default, an argument enables) --- interface/src/InterfaceActionFactory.cpp | 3 - interface/src/avatar/AvatarActionHold.cpp | 65 +++++- interface/src/avatar/AvatarActionHold.h | 7 + .../src/avatar/AvatarActionKinematicHold.cpp | 188 ------------------ .../src/avatar/AvatarActionKinematicHold.h | 47 ----- .../entities/src/EntityActionInterface.cpp | 22 +- .../entities/src/EntityActionInterface.h | 5 +- 7 files changed, 90 insertions(+), 247 deletions(-) delete mode 100644 interface/src/avatar/AvatarActionKinematicHold.cpp delete mode 100644 interface/src/avatar/AvatarActionKinematicHold.h diff --git a/interface/src/InterfaceActionFactory.cpp b/interface/src/InterfaceActionFactory.cpp index e2cbdac425..cf5dad8fa5 100644 --- a/interface/src/InterfaceActionFactory.cpp +++ b/interface/src/InterfaceActionFactory.cpp @@ -12,7 +12,6 @@ #include -#include #include #include @@ -29,8 +28,6 @@ EntityActionPointer interfaceActionFactory(EntityActionType type, const QUuid& i return (EntityActionPointer) new ObjectActionSpring(id, ownerEntity); case ACTION_TYPE_HOLD: return (EntityActionPointer) new AvatarActionHold(id, ownerEntity); - case ACTION_TYPE_KINEMATIC_HOLD: - return (EntityActionPointer) new AvatarActionKinematicHold(id, ownerEntity); } assert(false); diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 815293bf0d..bdd2a9c08a 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -75,12 +75,54 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { _active = true; }); if (gotLock) { - ObjectActionSpring::updateActionWorker(deltaTimeStep); + if (_kinematic) { + doKinematicUpdate(deltaTimeStep); + } else { + ObjectActionSpring::updateActionWorker(deltaTimeStep); + } } } } } +void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { + auto ownerEntity = _ownerEntity.lock(); + if (!ownerEntity) { + qDebug() << "AvatarActionHold::doKinematicUpdate -- no owning entity"; + return; + } + void* physicsInfo = ownerEntity->getPhysicsInfo(); + if (!physicsInfo) { + qDebug() << "AvatarActionHold::doKinematicUpdate -- no owning physics info"; + return; + } + ObjectMotionState* motionState = static_cast(physicsInfo); + btRigidBody* rigidBody = motionState ? motionState->getRigidBody() : nullptr; + if (!rigidBody) { + qDebug() << "AvatarActionHold::doKinematicUpdate -- no rigidBody"; + return; + } + + withWriteLock([&]{ + if (_kinematicSetVelocity) { + if (_previousSet) { + glm::vec3 positionalVelocity = (_positionalTarget - _previousPositionalTarget) / deltaTimeStep; + rigidBody->setLinearVelocity(glmToBullet(positionalVelocity)); + // back up along velocity a bit in order to smooth out a "vibrating" appearance + _positionalTarget -= positionalVelocity * deltaTimeStep / 2.0f; + } + } + + btTransform worldTrans = rigidBody->getWorldTransform(); + worldTrans.setOrigin(glmToBullet(_positionalTarget)); + worldTrans.setRotation(glmToBullet(_rotationalTarget)); + rigidBody->setWorldTransform(worldTrans); + + _previousPositionalTarget = _positionalTarget; + _previousRotationalTarget = _rotationalTarget; + _previousSet = true; + }); +} bool AvatarActionHold::updateArguments(QVariantMap arguments) { glm::vec3 relativePosition; @@ -88,6 +130,8 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { float timeScale; QString hand; QUuid holderID; + bool kinematic; + bool kinematicSetVelocity; bool needUpdate = false; bool somethingChanged = ObjectAction::updateArguments(arguments); @@ -120,12 +164,27 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { auto myAvatar = DependencyManager::get()->getMyAvatar(); holderID = myAvatar->getSessionUUID(); + ok = true; + kinematic = EntityActionInterface::extractBooleanArgument("hold", arguments, "kinematic", ok, false); + if (!ok) { + _kinematic = false; + } + + ok = true; + kinematicSetVelocity = EntityActionInterface::extractBooleanArgument("hold", arguments, + "kinematic-set-velocity", ok, false); + if (!ok) { + _kinematicSetVelocity = false; + } + if (somethingChanged || relativePosition != _relativePosition || relativeRotation != _relativeRotation || timeScale != _linearTimeScale || hand != _hand || - holderID != _holderID) { + holderID != _holderID || + kinematic != _kinematic || + kinematicSetVelocity != _kinematicSetVelocity) { needUpdate = true; } }); @@ -139,6 +198,8 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { _angularTimeScale = _linearTimeScale; _hand = hand; _holderID = holderID; + _kinematic = kinematic; + _kinematicSetVelocity = kinematicSetVelocity; _active = true; auto ownerEntity = _ownerEntity.lock(); diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index 3cc70ced09..042e6a0f25 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -39,6 +39,13 @@ private: glm::quat _relativeRotation; QString _hand; QUuid _holderID; + + void doKinematicUpdate(float deltaTimeStep); + bool _kinematic = false; + bool _kinematicSetVelocity = false; + bool _previousSet = false; + glm::vec3 _previousPositionalTarget; + glm::quat _previousRotationalTarget; }; #endif // hifi_AvatarActionHold_h diff --git a/interface/src/avatar/AvatarActionKinematicHold.cpp b/interface/src/avatar/AvatarActionKinematicHold.cpp deleted file mode 100644 index 680363877f..0000000000 --- a/interface/src/avatar/AvatarActionKinematicHold.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// -// AvatarActionKinematicHold.cpp -// interface/src/avatar/ -// -// Created by Seth Alves 2015-6-9 -// 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 "QVariantGLM.h" -#include "avatar/MyAvatar.h" -#include "avatar/AvatarManager.h" - -#include "AvatarActionKinematicHold.h" - -const uint16_t AvatarActionKinematicHold::holdVersion = 1; - -AvatarActionKinematicHold::AvatarActionKinematicHold(const QUuid& id, EntityItemPointer ownerEntity) : - ObjectActionSpring(id, ownerEntity), - _relativePosition(glm::vec3(0.0f)), - _relativeRotation(glm::quat()), - _hand("right"), - _mine(false), - _previousPositionalTarget(Vectors::ZERO), - _previousRotationalTarget(Quaternions::IDENTITY) -{ - _type = ACTION_TYPE_KINEMATIC_HOLD; - #if WANT_DEBUG - qDebug() << "AvatarActionKinematicHold::AvatarActionKinematicHold"; - #endif -} - -AvatarActionKinematicHold::~AvatarActionKinematicHold() { - #if WANT_DEBUG - qDebug() << "AvatarActionKinematicHold::~AvatarActionKinematicHold"; - #endif -} - -void AvatarActionKinematicHold::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; - } - - assert(deltaTimeStep > 0.0f); - - 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(); - } - - rotation = palmRotation * _relativeRotation; - offset = rotation * _relativePosition; - position = palmPosition + offset; - }); - - if (gotLock) { - gotLock = withTryWriteLock([&]{ - if (_positionalTarget != position || _rotationalTarget != rotation) { - _positionalTarget = position; - _rotationalTarget = rotation; - auto ownerEntity = _ownerEntity.lock(); - if (ownerEntity) { - ownerEntity->setActionDataDirty(true); - void* physicsInfo = ownerEntity->getPhysicsInfo(); - if (physicsInfo) { - ObjectMotionState* motionState = static_cast(physicsInfo); - btRigidBody* rigidBody = motionState ? motionState->getRigidBody() : nullptr; - if (!rigidBody) { - qDebug() << "ObjectActionSpring::updateActionWorker no rigidBody"; - return; - } - - if (_setVelocity) { - if (_previousSet) { - glm::vec3 positionalVelocity = (_positionalTarget - _previousPositionalTarget) / deltaTimeStep; - rigidBody->setLinearVelocity(glmToBullet(positionalVelocity)); - // back up along velocity a bit in order to smooth out a "vibrating" appearance - _positionalTarget -= positionalVelocity * deltaTimeStep / 2.0f; - } - } - - btTransform worldTrans = rigidBody->getWorldTransform(); - worldTrans.setOrigin(glmToBullet(_positionalTarget)); - worldTrans.setRotation(glmToBullet(_rotationalTarget)); - rigidBody->setWorldTransform(worldTrans); - - _previousPositionalTarget = _positionalTarget; - _previousRotationalTarget = _rotationalTarget; - _previousSet = true; - } - } - } - }); - } - - if (gotLock) { - ObjectActionSpring::updateActionWorker(deltaTimeStep); - } -} - - -bool AvatarActionKinematicHold::updateArguments(QVariantMap arguments) { - if (!ObjectAction::updateArguments(arguments)) { - return false; - } - bool ok = true; - glm::vec3 relativePosition = - EntityActionInterface::extractVec3Argument("kinematic-hold", arguments, "relativePosition", ok, false); - if (!ok) { - relativePosition = _relativePosition; - } - - ok = true; - glm::quat relativeRotation = - EntityActionInterface::extractQuatArgument("kinematic-hold", arguments, "relativeRotation", ok, false); - if (!ok) { - relativeRotation = _relativeRotation; - } - - ok = true; - QString hand = - EntityActionInterface::extractStringArgument("kinematic-hold", arguments, "hand", ok, false); - if (!ok || !(hand == "left" || hand == "right")) { - hand = _hand; - } - - ok = true; - int setVelocity = - EntityActionInterface::extractIntegerArgument("kinematic-hold", arguments, "setVelocity", ok, false); - if (!ok) { - setVelocity = false; - } - - if (relativePosition != _relativePosition - || relativeRotation != _relativeRotation - || hand != _hand) { - withWriteLock([&] { - _relativePosition = relativePosition; - _relativeRotation = relativeRotation; - _hand = hand; - _setVelocity = setVelocity; - - _mine = true; - _active = true; - activateBody(); - }); - } - return true; -} - - -QVariantMap AvatarActionKinematicHold::getArguments() { - QVariantMap arguments = ObjectAction::getArguments(); - withReadLock([&]{ - if (!_mine) { - arguments = ObjectActionSpring::getArguments(); - return; - } - - arguments["relativePosition"] = glmToQMap(_relativePosition); - arguments["relativeRotation"] = glmToQMap(_relativeRotation); - arguments["setVelocity"] = _setVelocity; - arguments["hand"] = _hand; - }); - return arguments; -} - - -void AvatarActionKinematicHold::deserialize(QByteArray serializedArguments) { - if (!_mine) { - ObjectActionSpring::deserialize(serializedArguments); - } -} diff --git a/interface/src/avatar/AvatarActionKinematicHold.h b/interface/src/avatar/AvatarActionKinematicHold.h deleted file mode 100644 index b4fceab1e7..0000000000 --- a/interface/src/avatar/AvatarActionKinematicHold.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// AvatarActionKinematicHold.h -// interface/src/avatar/ -// -// Created by Seth Alves 2015-10-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 -// - -#ifndef hifi_AvatarActionKinematicHold_h -#define hifi_AvatarActionKinematicHold_h - -#include - -#include -#include - -class AvatarActionKinematicHold : public ObjectActionSpring { -public: - AvatarActionKinematicHold(const QUuid& id, EntityItemPointer ownerEntity); - virtual ~AvatarActionKinematicHold(); - - virtual bool updateArguments(QVariantMap arguments); - virtual QVariantMap getArguments(); - - virtual void updateActionWorker(float deltaTimeStep); - - virtual void deserialize(QByteArray serializedArguments); - -private: - static const uint16_t holdVersion; - - glm::vec3 _relativePosition; - glm::quat _relativeRotation; - QString _hand; - bool _mine = false; - - bool _previousSet = false; - glm::vec3 _previousPositionalTarget; - glm::quat _previousRotationalTarget; - - bool _setVelocity = false; -}; - -#endif // hifi_AvatarActionKinematicHold_h diff --git a/libraries/entities/src/EntityActionInterface.cpp b/libraries/entities/src/EntityActionInterface.cpp index d874646b4b..3e88c61e49 100644 --- a/libraries/entities/src/EntityActionInterface.cpp +++ b/libraries/entities/src/EntityActionInterface.cpp @@ -100,9 +100,6 @@ EntityActionType EntityActionInterface::actionTypeFromString(QString actionTypeS if (normalizedActionTypeString == "hold") { return ACTION_TYPE_HOLD; } - if (normalizedActionTypeString == "kinematichold") { - return ACTION_TYPE_KINEMATIC_HOLD; - } qDebug() << "Warning -- EntityActionInterface::actionTypeFromString got unknown action-type name" << actionTypeString; return ACTION_TYPE_NONE; @@ -118,8 +115,6 @@ QString EntityActionInterface::actionTypeToString(EntityActionType actionType) { return "spring"; case ACTION_TYPE_HOLD: return "hold"; - case ACTION_TYPE_KINEMATIC_HOLD: - return "kinematic-hold"; } assert(false); return "none"; @@ -286,6 +281,23 @@ QString EntityActionInterface::extractStringArgument(QString objectName, QVarian return v; } +bool EntityActionInterface::extractBooleanArgument(QString objectName, QVariantMap arguments, + QString argumentName, bool& ok, bool required) { + if (!arguments.contains(argumentName)) { + if (required) { + qDebug() << objectName << "requires argument:" << argumentName; + } + ok = false; + return false; + } + + QVariant vV = arguments[argumentName]; + bool v = vV.toBool(); + return v; +} + + + QDataStream& operator<<(QDataStream& stream, const EntityActionType& entityActionType) { return stream << (quint16)entityActionType; diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index 49739e7da9..d97b5e8106 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -23,8 +23,7 @@ enum EntityActionType { ACTION_TYPE_NONE = 0, ACTION_TYPE_OFFSET = 1000, ACTION_TYPE_SPRING = 2000, - ACTION_TYPE_HOLD = 3000, - ACTION_TYPE_KINEMATIC_HOLD = 4000 + ACTION_TYPE_HOLD = 3000 }; @@ -66,6 +65,8 @@ public: QString argumentName, bool& ok, bool required = true); static QString extractStringArgument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok, bool required = true); + static bool extractBooleanArgument(QString objectName, QVariantMap arguments, + QString argumentName, bool& ok, bool required = true); protected: virtual glm::vec3 getPosition() = 0;