From 1d8db13f4123301a51f4919331ee99217501c89b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 10:56:47 -0700 Subject: [PATCH 01/33] switch to low-entity-server traffic hold --- interface/src/avatar/AvatarActionHold.cpp | 128 ++++++++++++++++------ interface/src/avatar/AvatarActionHold.h | 3 +- 2 files changed, 95 insertions(+), 36 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 3c57db084b..f12909e809 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -21,7 +21,8 @@ AvatarActionHold::AvatarActionHold(const QUuid& id, EntityItemPointer ownerEntit ObjectActionSpring(id, ownerEntity), _relativePosition(glm::vec3(0.0f)), _relativeRotation(glm::quat()), - _hand("right") + _hand("right"), + _holderID(QUuid()) { _type = ACTION_TYPE_HOLD; #if WANT_DEBUG @@ -39,39 +40,41 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { bool gotLock = false; glm::quat rotation; glm::vec3 position; - glm::vec3 offset; + std::shared_ptr holdingAvatar = nullptr; 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(); - } + QSharedPointer avatarManager = DependencyManager::get(); + AvatarSharedPointer holdingAvatarData = avatarManager->getAvatarBySessionID(_holderID); + holdingAvatar = std::static_pointer_cast(holdingAvatarData); - rotation = palmRotation * _relativeRotation; - offset = rotation * _relativePosition; - position = palmPosition + offset; + 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 (gotLock) { - gotLock = withTryWriteLock([&]{ - _positionalTarget = position; - _rotationalTarget = rotation; - _positionalTargetSet = true; - _rotationalTargetSet = true; - auto ownerEntity = _ownerEntity.lock(); - if (ownerEntity) { - ownerEntity->setActionDataDirty(true); - } - }); - } - if (gotLock) { - ObjectActionSpring::updateActionWorker(deltaTimeStep); + if (holdingAvatar) { + if (gotLock) { + gotLock = withTryWriteLock([&]{ + _positionalTarget = position; + _rotationalTarget = rotation; + }); + } + if (gotLock) { + ObjectActionSpring::updateActionWorker(deltaTimeStep); + } } } @@ -115,10 +118,11 @@ 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 + || holderID != _holderID) { needUpdate = true; } }); @@ -131,6 +135,7 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { _linearTimeScale = glm::max(MIN_TIMESCALE, timeScale); _angularTimeScale = _linearTimeScale; _hand = hand; + _holderID = holderID; _active = true; auto ownerEntity = _ownerEntity.lock(); @@ -147,6 +152,7 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { QVariantMap AvatarActionHold::getArguments() { QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&]{ + arguments["holderID"] = _holderID; arguments["relativePosition"] = glmToQMap(_relativePosition); arguments["relativeRotation"] = glmToQMap(_relativeRotation); arguments["timeScale"] = _linearTimeScale; @@ -156,9 +162,61 @@ QVariantMap AvatarActionHold::getArguments() { } QByteArray AvatarActionHold::serialize() const { - return ObjectActionSpring::serialize(); + 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; } void AvatarActionHold::deserialize(QByteArray serializedArguments) { - assert(false); + 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; + }); } diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index 840ba41c28..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 shouldSuppressLocationEdits() { return false; } + virtual bool shouldSuppressLocationEdits() { return true; } private: static const uint16_t holdVersion; @@ -38,6 +38,7 @@ private: glm::vec3 _relativePosition; glm::quat _relativeRotation; QString _hand; + QUuid _holderID; }; #endif // hifi_AvatarActionHold_h From a70ba4cd5a66c91c4fc6504f351b6a6f367dfa8d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 11:42:53 -0700 Subject: [PATCH 02/33] add some accessors --- interface/src/avatar/Avatar.h | 2 ++ interface/src/avatar/MyAvatar.h | 2 ++ libraries/animation/src/Rig.cpp | 7 +++++++ libraries/render-utils/src/Model.h | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 9a46a145c2..1ad4411619 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -174,6 +174,8 @@ public: void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; } AvatarMotionState* getMotionState() { return _motionState; } + virtual RigPointer getRig() const { return _skeletonModel.getRig(); } + public slots: glm::vec3 getLeftPalmPosition(); glm::vec3 getLeftPalmVelocity(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 7347419fee..eb907de4ef 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -183,6 +183,8 @@ public: glm::quat getCustomListenOrientation() { return _customListenOrientation; } void setCustomListenOrientation(glm::quat customListenOrientation) { _customListenOrientation = customListenOrientation; } + virtual RigPointer getRig() const { return _rig; } + public slots: void increaseSize(); void decreaseSize(); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 25f28a3f64..241fdf10bc 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -50,6 +50,13 @@ void Rig::HeadParameters::dump() const { qCDebug(animation, " isTalking = %s", isTalking ? "true" : "false"); } +// QString Rig::HeadParameters::dumpJoint(int jointIndex) const { +// QString out = ""; +// out += ...; +// JointState& state = _jointStates[i]; +// int parentIndex = state.getParentIndex(); +// } + void insertSorted(QList& handles, const AnimationHandlePointer& handle) { for (QList::iterator it = handles.begin(); it != handles.end(); it++) { if (handle->getPriority() > (*it)->getPriority()) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index e3a9ce9ac3..f5d5f40363 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -198,6 +198,10 @@ public: return ((index < 0) && (index >= _blendshapeCoefficients.size())) ? 0.0f : _blendshapeCoefficients.at(index); } + virtual RigPointer getRig() const { return _rig; } + + const glm::vec3& getRegistrationPoint() const { return _registrationPoint; } + protected: void setPupilDilation(float dilation) { _pupilDilation = dilation; } From 4903db45b14800cad0200f85b97bb1c7a13b0520 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 14:21:06 -0700 Subject: [PATCH 03/33] give other avatars an anim-skeleton --- interface/src/avatar/AvatarActionHold.cpp | 3 +++ interface/src/avatar/SkeletonModel.cpp | 12 ++++++------ libraries/animation/src/Rig.cpp | 8 +++++++- libraries/animation/src/Rig.h | 1 + libraries/render-utils/src/Model.cpp | 2 ++ 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index f12909e809..018108ac52 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -70,6 +70,9 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { gotLock = withTryWriteLock([&]{ _positionalTarget = position; _rotationalTarget = rotation; + _positionalTargetSet = true; + _rotationalTargetSet = true; + _active = true; }); } if (gotLock) { diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 312b7cbf44..28c7941c52 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -229,6 +229,12 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { Model::simulate(deltaTime, fullUpdate); + // let rig compute the model offset + glm::vec3 modelOffset; + if (_rig->getModelOffset(modelOffset)) { + setOffset(modelOffset); + } + if (!isActive() || !_owningAvatar->isMyAvatar()) { return; // only simulate for own avatar } @@ -246,12 +252,6 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { Hand* hand = _owningAvatar->getHand(); hand->getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex); - // let rig compute the model offset - glm::vec3 modelOffset; - if (_rig->getModelOffset(modelOffset)) { - setOffset(modelOffset); - } - // Don't Relax toward hand positions when in animGraph mode. if (!_rig->getEnableAnimGraph()) { const float HAND_RESTORATION_RATE = 0.25f; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 241fdf10bc..fd764964a4 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1245,12 +1245,18 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) { } } +void Rig::makeAnimSkeleton(const FBXGeometry& fbxGeometry) { + if (!_animSkeleton) { + _animSkeleton = std::make_shared(fbxGeometry); + } +} + void Rig::initAnimGraph(const QUrl& url, const FBXGeometry& fbxGeometry) { if (!_enableAnimGraph) { return; } - _animSkeleton = std::make_shared(fbxGeometry); + makeAnimSkeleton(fbxGeometry); // load the anim graph _animLoader.reset(new AnimNodeLoader(url)); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 71c27e7213..c9c42cbbb6 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -193,6 +193,7 @@ public: virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, float scale, float priority) = 0; + void makeAnimSkeleton(const FBXGeometry& fbxGeometry); void initAnimGraph(const QUrl& url, const FBXGeometry& fbxGeometry); AnimNode::ConstPointer getAnimNode() const { return _animNode; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 38f5ffdabe..6aae7ad1cb 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1147,6 +1147,8 @@ void Model::segregateMeshGroups() { const FBXGeometry& geometry = _geometry->getFBXGeometry(); const std::vector>& networkMeshes = _geometry->getMeshes(); + _rig->makeAnimSkeleton(geometry); + // all of our mesh vectors must match in size if ((int)networkMeshes.size() != geometry.meshes.size() || geometry.meshes.size() != _meshStates.size()) { From 487131dde1d55634065de7a0dfbf5838a1e28efe Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 14:52:38 -0700 Subject: [PATCH 04/33] cleanups --- interface/src/avatar/Avatar.h | 2 -- interface/src/avatar/AvatarActionHold.cpp | 10 +++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 1ad4411619..9a46a145c2 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -174,8 +174,6 @@ public: void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; } AvatarMotionState* getMotionState() { return _motionState; } - virtual RigPointer getRig() const { return _skeletonModel.getRig(); } - public slots: glm::vec3 getLeftPalmPosition(); glm::vec3 getLeftPalmVelocity(); diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 018108ac52..561a2bbcc5 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -121,11 +121,11 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { holderID = myAvatar->getSessionUUID(); if (somethingChanged || - relativePosition != _relativePosition - || relativeRotation != _relativeRotation - || timeScale != _linearTimeScale - || hand != _hand - || holderID != _holderID) { + relativePosition != _relativePosition || + relativeRotation != _relativeRotation || + timeScale != _linearTimeScale || + hand != _hand || + holderID != _holderID) { needUpdate = true; } }); From 462918ffcf1fc64f78c2fa7a4f32670500da33b1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 14:55:17 -0700 Subject: [PATCH 05/33] cleanups --- interface/src/avatar/MyAvatar.h | 2 -- libraries/animation/src/Rig.cpp | 7 ------- 2 files changed, 9 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index eb907de4ef..7347419fee 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -183,8 +183,6 @@ public: glm::quat getCustomListenOrientation() { return _customListenOrientation; } void setCustomListenOrientation(glm::quat customListenOrientation) { _customListenOrientation = customListenOrientation; } - virtual RigPointer getRig() const { return _rig; } - public slots: void increaseSize(); void decreaseSize(); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index fd764964a4..6fd6f5cbf9 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -50,13 +50,6 @@ void Rig::HeadParameters::dump() const { qCDebug(animation, " isTalking = %s", isTalking ? "true" : "false"); } -// QString Rig::HeadParameters::dumpJoint(int jointIndex) const { -// QString out = ""; -// out += ...; -// JointState& state = _jointStates[i]; -// int parentIndex = state.getParentIndex(); -// } - void insertSorted(QList& handles, const AnimationHandlePointer& handle) { for (QList::iterator it = handles.begin(); it != handles.end(); it++) { if (handle->getPriority() > (*it)->getPriority()) { From 0964180f2cbcbb801dc28e2bf99ba7ae51fdee02 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 17:10:47 -0700 Subject: [PATCH 06/33] code review --- interface/src/avatar/AvatarActionHold.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 561a2bbcc5..815293bf0d 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -74,9 +74,9 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { _rotationalTargetSet = true; _active = true; }); - } - if (gotLock) { - ObjectActionSpring::updateActionWorker(deltaTimeStep); + if (gotLock) { + ObjectActionSpring::updateActionWorker(deltaTimeStep); + } } } } From 359a318568f4fb8acc9777a901bc0cdf7c2b3dc3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 15 Oct 2015 20:23:06 -0700 Subject: [PATCH 07/33] 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; From 937959c1c1ea19e82c90b58558ffe481b01bc069 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 16 Oct 2015 09:57:27 -0700 Subject: [PATCH 08/33] cleanups --- libraries/entities/src/EntityActionInterface.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntityActionInterface.cpp b/libraries/entities/src/EntityActionInterface.cpp index 3e88c61e49..549aacbd0a 100644 --- a/libraries/entities/src/EntityActionInterface.cpp +++ b/libraries/entities/src/EntityActionInterface.cpp @@ -275,10 +275,7 @@ QString EntityActionInterface::extractStringArgument(QString objectName, QVarian ok = false; return ""; } - - QVariant vV = arguments[argumentName]; - QString v = vV.toString(); - return v; + return arguments[argumentName].toString(); } bool EntityActionInterface::extractBooleanArgument(QString objectName, QVariantMap arguments, @@ -290,10 +287,7 @@ bool EntityActionInterface::extractBooleanArgument(QString objectName, QVariantM ok = false; return false; } - - QVariant vV = arguments[argumentName]; - bool v = vV.toBool(); - return v; + return arguments[argumentName].toBool(); } From 966499b9e5e5edf7d07a4477a34605b0607e1318 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 16 Oct 2015 10:17:17 -0700 Subject: [PATCH 09/33] continually activate (in the bullet sense) a held object --- interface/src/avatar/AvatarActionHold.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index bdd2a9c08a..6568f8932e 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -78,6 +78,7 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { if (_kinematic) { doKinematicUpdate(deltaTimeStep); } else { + activateBody(); ObjectActionSpring::updateActionWorker(deltaTimeStep); } } From fe709a9397951ae67e7e9f224fa03a6c03bea1b4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 16 Oct 2015 10:53:33 -0700 Subject: [PATCH 10/33] keep object active in kinematic mode, also --- interface/src/avatar/AvatarActionHold.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 6568f8932e..0264777164 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -123,6 +123,8 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) { _previousRotationalTarget = _rotationalTarget; _previousSet = true; }); + + activateBody(); } bool AvatarActionHold::updateArguments(QVariantMap arguments) { From 066696e201b5738d95ca8fee7257a6c0b93c6ff7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 16 Oct 2015 11:18:41 -0700 Subject: [PATCH 11/33] don't go into continue-far-grabbing-non-colliding mode. --- examples/controllers/handControllerGrab.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 44aa1146d4..c607946f2f 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -393,7 +393,8 @@ function MyController(hand, triggerAction) { this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR); // the action was set up on a previous call. update the targets. - var radius = Math.max(Vec3.distance(this.currentObjectPosition, handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, DISTANCE_HOLDING_RADIUS_FACTOR); + var radius = Math.max(Vec3.distance(this.currentObjectPosition, handControllerPosition) * + DISTANCE_HOLDING_RADIUS_FACTOR, DISTANCE_HOLDING_RADIUS_FACTOR); // how far did avatar move this timestep? var currentPosition = MyAvatar.position; @@ -492,7 +493,8 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - lifetime: ACTION_LIFETIME + lifetime: ACTION_LIFETIME, + // kinematic: true, }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; @@ -544,7 +546,8 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - lifetime: ACTION_LIFETIME + lifetime: ACTION_LIFETIME, + // kinematic: true }); this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); } @@ -576,7 +579,9 @@ function MyController(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); } Entities.callEntityMethod(this.grabbedEntity, "startFarGrabNonColliding"); - this.setState(STATE_CONTINUE_FAR_GRABBING_NON_COLLIDING); + // TODO -- figure out how to make this work. + // this.setState(STATE_CONTINUE_FAR_GRABBING_NON_COLLIDING); + this.setState(STATE_RELEASE); }; this.continueNearGrabbingNonColliding = function() { From c98685f6d390d7d6e1f2d09a3b3fae60c6a0673b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 16 Oct 2015 11:39:27 -0700 Subject: [PATCH 12/33] in STATE_CONTINUE_FAR_GRABBING_NON_COLLIDING, when the ray moves off of the entity, switch back to search state --- examples/controllers/handControllerGrab.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index c607946f2f..faa90efdff 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -579,9 +579,7 @@ function MyController(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); } Entities.callEntityMethod(this.grabbedEntity, "startFarGrabNonColliding"); - // TODO -- figure out how to make this work. - // this.setState(STATE_CONTINUE_FAR_GRABBING_NON_COLLIDING); - this.setState(STATE_RELEASE); + this.setState(STATE_CONTINUE_FAR_GRABBING_NON_COLLIDING); }; this.continueNearGrabbingNonColliding = function() { @@ -589,7 +587,7 @@ function MyController(hand, triggerAction) { this.setState(STATE_RELEASE); return; } - + Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; @@ -605,6 +603,16 @@ function MyController(hand, triggerAction) { direction: Quat.getUp(this.getHandRotation()) }; + var now = Date.now(); + if (now - this.lastPickTime > MSECS_PER_SEC / PICKS_PER_SECOND_PER_HAND) { + var intersection = Entities.findRayIntersection(pickRay, true); + this.lastPickTime = now; + if (intersection.entityID != this.grabbedEntity) { + this.setState(STATE_RELEASE); + return; + } + } + this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); Entities.callEntityMethod(this.grabbedEntity, "continueFarGrabbingNonColliding"); }; From 1f3b92577d15054948c5f9198900728879732565 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 17 Oct 2015 20:08:25 -0700 Subject: [PATCH 13/33] update _model's location anytime it doesn't match the entity's location --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 8a973c88a9..bfed81a944 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -298,7 +298,11 @@ void RenderableModelEntityItem::render(RenderArgs* args) { } bool movingOrAnimating = isMoving() || isAnimatingSomething(); - if ((movingOrAnimating || _needsInitialSimulation) && _model->isActive() && _dimensionsInitialized) { + if ((movingOrAnimating || + _needsInitialSimulation || + _model->getTranslation() != getPosition() || + _model->getRotation() != getRotation()) + && _model->isActive() && _dimensionsInitialized) { _model->setScaleToFit(true, getDimensions()); _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); _model->setRotation(getRotation()); From 742e48b0c8df9aac19b133b9c9607f93a29f064e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 09:48:34 -0700 Subject: [PATCH 14/33] try another way of fixing held object snagging at slow velocity --- .../src/RenderableModelEntityItem.cpp | 7 ++++--- libraries/physics/src/EntityMotionState.cpp | 15 +++++++++++++++ libraries/physics/src/ObjectMotionState.cpp | 10 +--------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index bfed81a944..e028ee89ea 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -299,9 +299,10 @@ void RenderableModelEntityItem::render(RenderArgs* args) { bool movingOrAnimating = isMoving() || isAnimatingSomething(); if ((movingOrAnimating || - _needsInitialSimulation || - _model->getTranslation() != getPosition() || - _model->getRotation() != getRotation()) + _needsInitialSimulation // || + // _model->getTranslation() != getPosition() || + // _model->getRotation() != getRotation() + ) && _model->isActive() && _dimensionsInitialized) { _model->setScaleToFit(true, getDimensions()); _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index c458c2e1f8..b6487103d1 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include #include @@ -30,6 +32,11 @@ static const quint8 STEPS_TO_DECIDE_BALLISTIC = 4; const uint32_t LOOPS_FOR_SIMULATION_ORPHAN = 50; const quint64 USECS_BETWEEN_OWNERSHIP_BIDS = USECS_PER_SECOND / 5; +// NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates +// to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving +// just under this velocity threshold would trigger an update about V/dX times per second. +const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec + #ifdef WANT_DEBUG_ENTITY_TREE_LOCKS bool EntityMotionState::entityTreeIsLocked() const { EntityTreeElementPointer element = _entity ? _entity->getElement() : nullptr; @@ -548,6 +555,10 @@ void EntityMotionState::resetMeasuredBodyAcceleration() { _lastMeasureStep = ObjectMotionState::getWorldSimulationStep(); if (_body) { _lastVelocity = getBodyLinearVelocity(); + // if _lastVelocity is too slow, set it to zero + if (glm::length2(_lastVelocity) < MIN_LINEAR_SPEED_SQUARED) { + _lastVelocity *= 0.0f; + } } else { _lastVelocity = glm::vec3(0.0f); } @@ -567,6 +578,10 @@ void EntityMotionState::measureBodyAcceleration() { // Note: the integration equation for velocity uses damping: v1 = (v0 + a * dt) * (1 - D)^dt // hence the equation for acceleration is: a = (v1 / (1 - D)^dt - v0) / dt glm::vec3 velocity = getBodyLinearVelocity(); + if (glm::length2(velocity) < MIN_LINEAR_SPEED_SQUARED) { + velocity *= 0.0f; + } + _measuredAcceleration = (velocity / powf(1.0f - _body->getLinearDamping(), dt) - _lastVelocity) * invDt; _lastVelocity = velocity; if (numSubsteps > PHYSICS_ENGINE_MAX_NUM_SUBSTEPS) { diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index d2c152d876..8bd6c3c983 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -80,16 +80,8 @@ void ObjectMotionState::setBodyGravity(const glm::vec3& gravity) const { } glm::vec3 ObjectMotionState::getBodyLinearVelocity() const { - // returns the body's velocity unless it is moving too slow in which case returns zero + // returns the body's velocity btVector3 velocity = _body->getLinearVelocity(); - - // NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates - // to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving - // just under this velocity threshold would trigger an update about V/dX times per second. - const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec - if (velocity.length2() < MIN_LINEAR_SPEED_SQUARED) { - velocity *= 0.0f; - } return bulletToGLM(velocity); } From fbe3cb9511c8d2e143e23e0dd7f3dad668d8f72e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 09:56:51 -0700 Subject: [PATCH 15/33] try another way of fixing held object snagging at slow velocity --- libraries/physics/src/EntityMotionState.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index b6487103d1..2290f5832e 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -256,6 +256,10 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { _serverPosition = bulletToGLM(xform.getOrigin()); _serverRotation = bulletToGLM(xform.getRotation()); _serverVelocity = getBodyLinearVelocity(); + if (glm::length2(_serverVelocity) < MIN_LINEAR_SPEED_SQUARED) { + _serverVelocity *= 0.0f; + } + _serverAngularVelocity = bulletToGLM(_body->getAngularVelocity()); _lastStep = simulationStep; _serverActionData = _entity->getActionData(); From 26dcaeb0562af7ce4c52c9abf7cd65a83f307b8c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 10:10:43 -0700 Subject: [PATCH 16/33] try another way of fixing held object snagging at slow velocity --- libraries/physics/src/EntityMotionState.cpp | 7 ++++++- libraries/physics/src/ObjectMotionState.cpp | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 2290f5832e..a8194f76e3 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -194,7 +194,12 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { _entity->setPosition(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset()); _entity->setRotation(bulletToGLM(worldTrans.getRotation())); - _entity->setVelocity(getBodyLinearVelocity()); + glm::vec3 velocity = getBodyLinearVelocity(); + if (glm::length2(velocity) < MIN_LINEAR_SPEED_SQUARED) { + velocity *= 0.0f; + } + _entity->setVelocity(velocity); + _entity->setAngularVelocity(getBodyAngularVelocity()); _entity->setLastSimulated(usecTimestampNow()); diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 8bd6c3c983..7a384e32d1 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -80,9 +80,7 @@ void ObjectMotionState::setBodyGravity(const glm::vec3& gravity) const { } glm::vec3 ObjectMotionState::getBodyLinearVelocity() const { - // returns the body's velocity - btVector3 velocity = _body->getLinearVelocity(); - return bulletToGLM(velocity); + return bulletToGLM(_body->getLinearVelocity()); } glm::vec3 ObjectMotionState::getObjectLinearVelocityChange() const { From 2bdcb256d8103fa667304dce8b46cba687a4c691 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 10:26:37 -0700 Subject: [PATCH 17/33] try another way of fixing held object snagging at slow velocity --- libraries/physics/src/EntityMotionState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index a8194f76e3..6ddb8b6b45 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -302,7 +302,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { _serverPosition += dt * _serverVelocity; } - if (_serverActionData != _entity->getActionData()) { + if (_serverActionData != _entity->getActionData() || _entity->getActionDataDirty()) { setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY); return true; } From c5a5f26e6ac8fe93351576e5a51fa843e9f056f1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 10:27:35 -0700 Subject: [PATCH 18/33] try another way of fixing held object snagging at slow velocity --- libraries/entities/src/EntityItem.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index f438e3f28b..3560097083 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -407,6 +407,7 @@ public: QVariantMap getActionArguments(const QUuid& actionID) const; void deserializeActions(); void setActionDataDirty(bool value) const { _actionDataDirty = value; } + bool getActionDataDirty(bool value) const { return _actionDataDirty; } bool shouldSuppressLocationEdits() const; protected: From 5c031a38c78748486d243dccdc73bdf92713ff8b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 10:29:30 -0700 Subject: [PATCH 19/33] try another way of fixing held object snagging at slow velocity --- libraries/entities/src/EntityItem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 3560097083..9ecc1d25a0 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -407,7 +407,7 @@ public: QVariantMap getActionArguments(const QUuid& actionID) const; void deserializeActions(); void setActionDataDirty(bool value) const { _actionDataDirty = value; } - bool getActionDataDirty(bool value) const { return _actionDataDirty; } + bool getActionDataDirty() const { return _actionDataDirty; } bool shouldSuppressLocationEdits() const; protected: From 46e5bf043599be5c4c5c2cf959023b0129bace62 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 11:59:03 -0700 Subject: [PATCH 20/33] take entity-server clock-skew into account when handling action expiration times --- interface/src/InterfaceActionFactory.cpp | 1 + interface/src/avatar/AvatarActionHold.cpp | 3 ++- libraries/entities/src/EntityItem.cpp | 6 ++++++ libraries/entities/src/EntityItem.h | 7 ++++++- libraries/physics/src/EntityMotionState.cpp | 2 +- libraries/physics/src/ObjectAction.cpp | 16 ++++++++++++++++ libraries/physics/src/ObjectAction.h | 2 ++ libraries/physics/src/ObjectActionOffset.cpp | 3 ++- libraries/physics/src/ObjectActionSpring.cpp | 3 ++- 9 files changed, 38 insertions(+), 5 deletions(-) diff --git a/interface/src/InterfaceActionFactory.cpp b/interface/src/InterfaceActionFactory.cpp index cf5dad8fa5..f814df9a99 100644 --- a/interface/src/InterfaceActionFactory.cpp +++ b/interface/src/InterfaceActionFactory.cpp @@ -66,6 +66,7 @@ EntityActionPointer InterfaceActionFactory::factoryBA(EntityItemPointer ownerEnt if (action) { action->deserialize(data); if (action->lifetimeIsOver()) { + qDebug() << "InterfaceActionFactory::factoryBA lifetimeIsOver during action creation"; return nullptr; } } diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 0264777164..4d07ecb5e3 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -243,7 +243,7 @@ QByteArray AvatarActionHold::serialize() const { dataStream << _linearTimeScale; dataStream << _hand; - dataStream << _expires; + dataStream << _expires + getEntityServerClockSkew(); dataStream << _tag; }); @@ -276,6 +276,7 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) { dataStream >> _hand; dataStream >> _expires; + _expires -= getEntityServerClockSkew(); dataStream >> _tag; #if WANT_DEBUG diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 5b262b273b..9b3821b56a 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -342,6 +342,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef "ERROR CASE...args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU"; return 0; } + setSourceUUID(args.sourceUUID); args.entitiesPerPacket++; @@ -1534,6 +1535,8 @@ bool EntityItem::addActionInternal(EntitySimulation* simulation, EntityActionPoi if (success) { _allActionsDataCache = newDataCache; _dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; + } else { + qDebug() << "EntityItem::addActionInternal -- serializeActions failed"; } return success; } @@ -1628,6 +1631,7 @@ void EntityItem::deserializeActionsInternal() { quint64 now = usecTimestampNow(); if (!_element) { + qDebug() << "EntityItem::deserializeActionsInternal -- no _element"; return; } @@ -1670,6 +1674,8 @@ void EntityItem::deserializeActionsInternal() { if (action) { entity->addActionInternal(simulation, action); action->locallyAddedButNotYetReceived = false; + } else { + qDebug() << "EntityItem::deserializeActionsInternal -- action creation failed"; } } } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 9ecc1d25a0..858dc7e326 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -407,9 +407,12 @@ public: QVariantMap getActionArguments(const QUuid& actionID) const; void deserializeActions(); void setActionDataDirty(bool value) const { _actionDataDirty = value; } - bool getActionDataDirty() const { return _actionDataDirty; } bool shouldSuppressLocationEdits() const; + void setSourceUUID(const QUuid& sourceUUID) { _sourceUUID = sourceUUID; } + const QUuid& getSourceUUID() const { return _sourceUUID; } + bool matchesSourceUUID(const QUuid& sourceUUID) const { return _sourceUUID == sourceUUID; } + protected: const QByteArray getActionDataInternal() const; @@ -510,6 +513,8 @@ protected: // _previouslyDeletedActions is used to avoid an action being re-added due to server round-trip lag static quint64 _rememberDeletedActionTime; mutable QHash _previouslyDeletedActions; + + QUuid _sourceUUID; /// the server node UUID we came from }; #endif // hifi_EntityItem_h diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 6ddb8b6b45..a8194f76e3 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -302,7 +302,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { _serverPosition += dt * _serverVelocity; } - if (_serverActionData != _entity->getActionData() || _entity->getActionDataDirty()) { + if (_serverActionData != _entity->getActionData()) { setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY); return true; } diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 2f0de6d0ab..10a3d8d110 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -62,6 +62,22 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta updateActionWorker(deltaTimeStep); } +int ObjectAction::getEntityServerClockSkew() { + auto nodeList = DependencyManager::get(); + + auto ownerEntity = _ownerEntity.lock(); + if (!ownerEntity) { + return 0; + } + + const QUuid& entityServerNodeID = ownerEntity->getSourceUUID(); + auto entityServerNode = nodeList->nodeWithUUID(entityServerNodeID); + if (entityServerNode) { + return entityServerNode->getClockSkewUsec(); + } + return 0; +} + bool ObjectAction::updateArguments(QVariantMap arguments) { bool somethingChanged = false; diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 5c29ac9892..4a531ea70d 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -50,6 +50,8 @@ public: protected: + int getEntityServerClockSkew(); + virtual btRigidBody* getRigidBody(); virtual glm::vec3 getPosition(); virtual void setPosition(glm::vec3 position); diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index d01178dcc3..b6edf22ffc 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -160,7 +160,7 @@ QByteArray ObjectActionOffset::serialize() const { dataStream << _linearDistance; dataStream << _linearTimeScale; dataStream << _positionalTargetSet; - dataStream << _expires; + dataStream << _expires + getEntityServerClockSkew(); dataStream << _tag; }); @@ -190,6 +190,7 @@ void ObjectActionOffset::deserialize(QByteArray serializedArguments) { dataStream >> _linearTimeScale; dataStream >> _positionalTargetSet; dataStream >> _expires; + _expires -= getEntityServerClockSkew(); dataStream >> _tag; _active = true; }); diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index a99cfdd747..a74756eb53 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -198,7 +198,7 @@ QByteArray ObjectActionSpring::serialize() const { dataStream << _rotationalTarget; dataStream << _angularTimeScale; dataStream << _rotationalTargetSet; - dataStream << _expires; + dataStream << _expires + getEntityServerClockSkew(); dataStream << _tag; }); @@ -233,6 +233,7 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { dataStream >> _rotationalTargetSet; dataStream >> _expires; + _expires -= getEntityServerClockSkew(); dataStream >> _tag; _active = true; From f96e9eb1e80d1b47a6ddf493d27e3100e8d8a67d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 12:04:55 -0700 Subject: [PATCH 21/33] fuck you, const! --- libraries/physics/src/ObjectAction.cpp | 2 +- libraries/physics/src/ObjectAction.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 10a3d8d110..ce4ebfd22f 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -62,7 +62,7 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta updateActionWorker(deltaTimeStep); } -int ObjectAction::getEntityServerClockSkew() { +int ObjectAction::getEntityServerClockSkew() const { auto nodeList = DependencyManager::get(); auto ownerEntity = _ownerEntity.lock(); diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 4a531ea70d..98e58475c6 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -50,7 +50,7 @@ public: protected: - int getEntityServerClockSkew(); + int getEntityServerClockSkew() const; virtual btRigidBody* getRigidBody(); virtual glm::vec3 getPosition(); From ac990056021a8733a6422d5d921d9e8fac8fbf0e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 12:13:08 -0700 Subject: [PATCH 22/33] reverting a change to try to see sticking problem again --- libraries/physics/src/ObjectMotionState.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 7a384e32d1..144ba1e100 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -80,7 +80,19 @@ void ObjectMotionState::setBodyGravity(const glm::vec3& gravity) const { } glm::vec3 ObjectMotionState::getBodyLinearVelocity() const { - return bulletToGLM(_body->getLinearVelocity()); + + btVector3 velocity = _body->getLinearVelocity(); + + // NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates + // to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving + // just under this velocity threshold would trigger an update about V/dX times per second. + const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec + if (velocity.length2() < MIN_LINEAR_SPEED_SQUARED) { + velocity *= 0.0f; + } + return bulletToGLM(velocity); + + // return bulletToGLM(_body->getLinearVelocity()); } glm::vec3 ObjectMotionState::getObjectLinearVelocityChange() const { From 113321184d58a4ce081773017adfa5ed9a659dda Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 12:21:26 -0700 Subject: [PATCH 23/33] if model RegistrationPoint doesn't match entityItem's, update it --- .../src/RenderableModelEntityItem.cpp | 12 ++++++------ libraries/physics/src/EntityMotionState.cpp | 9 +-------- libraries/physics/src/ObjectMotionState.cpp | 14 +------------- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index e028ee89ea..e604bdb925 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -299,22 +299,22 @@ void RenderableModelEntityItem::render(RenderArgs* args) { bool movingOrAnimating = isMoving() || isAnimatingSomething(); if ((movingOrAnimating || - _needsInitialSimulation // || - // _model->getTranslation() != getPosition() || - // _model->getRotation() != getRotation() - ) + _needsInitialSimulation || + _model->getTranslation() != getPosition() || + _model->getRotation() != getRotation() || + _model->getRegistrationPoint() != getRegistrationPoint()) && _model->isActive() && _dimensionsInitialized) { _model->setScaleToFit(true, getDimensions()); _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); _model->setRotation(getRotation()); _model->setTranslation(getPosition()); - + // make sure to simulate so everything gets set up correctly for rendering { PerformanceTimer perfTimer("_model->simulate"); _model->simulate(0.0f); } - + _needsInitialSimulation = false; } } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index a8194f76e3..1745984add 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -193,15 +193,8 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { measureBodyAcceleration(); _entity->setPosition(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset()); _entity->setRotation(bulletToGLM(worldTrans.getRotation())); - - glm::vec3 velocity = getBodyLinearVelocity(); - if (glm::length2(velocity) < MIN_LINEAR_SPEED_SQUARED) { - velocity *= 0.0f; - } - _entity->setVelocity(velocity); - + _entity->setVelocity(getBodyLinearVelocity()); _entity->setAngularVelocity(getBodyAngularVelocity()); - _entity->setLastSimulated(usecTimestampNow()); if (_entity->getSimulatorID().isNull()) { diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 144ba1e100..7a384e32d1 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -80,19 +80,7 @@ void ObjectMotionState::setBodyGravity(const glm::vec3& gravity) const { } glm::vec3 ObjectMotionState::getBodyLinearVelocity() const { - - btVector3 velocity = _body->getLinearVelocity(); - - // NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates - // to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving - // just under this velocity threshold would trigger an update about V/dX times per second. - const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec - if (velocity.length2() < MIN_LINEAR_SPEED_SQUARED) { - velocity *= 0.0f; - } - return bulletToGLM(velocity); - - // return bulletToGLM(_body->getLinearVelocity()); + return bulletToGLM(_body->getLinearVelocity()); } glm::vec3 ObjectMotionState::getObjectLinearVelocityChange() const { From 6f30a3c17856c2120a440e5a3cb1fa45319035c1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 13:56:30 -0700 Subject: [PATCH 24/33] new method -- ObjectMotionState::getBodyLinearVelocityGTSigma --- libraries/physics/src/EntityMotionState.cpp | 22 +++------------------ libraries/physics/src/ObjectMotionState.cpp | 13 ++++++++++++ libraries/physics/src/ObjectMotionState.h | 1 + 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 1745984add..6832b8daff 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -32,11 +32,6 @@ static const quint8 STEPS_TO_DECIDE_BALLISTIC = 4; const uint32_t LOOPS_FOR_SIMULATION_ORPHAN = 50; const quint64 USECS_BETWEEN_OWNERSHIP_BIDS = USECS_PER_SECOND / 5; -// NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates -// to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving -// just under this velocity threshold would trigger an update about V/dX times per second. -const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec - #ifdef WANT_DEBUG_ENTITY_TREE_LOCKS bool EntityMotionState::entityTreeIsLocked() const { EntityTreeElementPointer element = _entity ? _entity->getElement() : nullptr; @@ -253,11 +248,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { btTransform xform = _body->getWorldTransform(); _serverPosition = bulletToGLM(xform.getOrigin()); _serverRotation = bulletToGLM(xform.getRotation()); - _serverVelocity = getBodyLinearVelocity(); - if (glm::length2(_serverVelocity) < MIN_LINEAR_SPEED_SQUARED) { - _serverVelocity *= 0.0f; - } - + _serverVelocity = getBodyLinearVelocityGTSigma(); _serverAngularVelocity = bulletToGLM(_body->getAngularVelocity()); _lastStep = simulationStep; _serverActionData = _entity->getActionData(); @@ -556,11 +547,7 @@ void EntityMotionState::bump(quint8 priority) { void EntityMotionState::resetMeasuredBodyAcceleration() { _lastMeasureStep = ObjectMotionState::getWorldSimulationStep(); if (_body) { - _lastVelocity = getBodyLinearVelocity(); - // if _lastVelocity is too slow, set it to zero - if (glm::length2(_lastVelocity) < MIN_LINEAR_SPEED_SQUARED) { - _lastVelocity *= 0.0f; - } + _lastVelocity = getBodyLinearVelocityGTSigma(); } else { _lastVelocity = glm::vec3(0.0f); } @@ -579,10 +566,7 @@ void EntityMotionState::measureBodyAcceleration() { // Note: the integration equation for velocity uses damping: v1 = (v0 + a * dt) * (1 - D)^dt // hence the equation for acceleration is: a = (v1 / (1 - D)^dt - v0) / dt - glm::vec3 velocity = getBodyLinearVelocity(); - if (glm::length2(velocity) < MIN_LINEAR_SPEED_SQUARED) { - velocity *= 0.0f; - } + glm::vec3 velocity = getBodyLinearVelocityGTSigma(); _measuredAcceleration = (velocity / powf(1.0f - _body->getLinearDamping(), dt) - _lastVelocity) * invDt; _lastVelocity = velocity; diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 7a384e32d1..4f3d0396c6 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -83,6 +83,19 @@ glm::vec3 ObjectMotionState::getBodyLinearVelocity() const { return bulletToGLM(_body->getLinearVelocity()); } +glm::vec3 ObjectMotionState::getBodyLinearVelocityGTSigma() const { + // NOTE: the threshold to use here relates to the linear displacement threshold (dX) for sending updates + // to objects that are tracked server-side (e.g. entities which use dX = 2mm). Hence an object moving + // just under this velocity threshold would trigger an update about V/dX times per second. + const float MIN_LINEAR_SPEED_SQUARED = 0.0036f; // 6 mm/sec + + glm::vec3 velocity = bulletToGLM(_body->getLinearVelocity()); + if (glm::length2(velocity) < MIN_LINEAR_SPEED_SQUARED) { + velocity *= 0.0f; + } + return velocity; +} + glm::vec3 ObjectMotionState::getObjectLinearVelocityChange() const { return glm::vec3(0.0f); // Subclasses override where meaningful. } diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index ec98f8858f..450ac34a90 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -89,6 +89,7 @@ public: void setBodyGravity(const glm::vec3& gravity) const; glm::vec3 getBodyLinearVelocity() const; + glm::vec3 getBodyLinearVelocityGTSigma() const; glm::vec3 getBodyAngularVelocity() const; virtual glm::vec3 getObjectLinearVelocityChange() const; From 8fbf081223396acd9bf1a46a04a04b54065d6a5c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 14:51:18 -0700 Subject: [PATCH 25/33] git rid of sphere test --- examples/controllers/handControllerGrab.js | 113 ++++++++++----------- 1 file changed, 53 insertions(+), 60 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index faa90efdff..e6fedd8f25 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -34,18 +34,18 @@ var NO_INTERSECT_COLOR = { red: 10, green: 10, blue: 255}; // line color when pi var INTERSECT_COLOR = { red: 250, green: 10, blue: 10}; // line color when pick hits var LINE_ENTITY_DIMENSIONS = { x: 1000, y: 1000,z: 1000}; var LINE_LENGTH = 500; - +var PICK_MAX_DISTANCE = 500; // max length of pick-ray ///////////////////////////////////////////////////////////////// // // near grabbing // -var GRAB_RADIUS = 0.3; // if the ray misses but an object is this close, it will still be selected var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable. -var NEAR_PICK_MAX_DISTANCE = 0.6; // max length of pick-ray for close grabbing to be selected +var NEAR_PICK_MAX_DISTANCE = 0.1; // max length of pick-ray for close grabbing to be selected var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things +var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object ///////////////////////////////////////////////////////////////// // @@ -256,12 +256,18 @@ function MyController(hand, triggerAction) { // the trigger is being pressed, do a ray test var handPosition = this.getHandPosition(); - var pickRay = { + var distantPickRay = { origin: handPosition, - direction: Quat.getUp(this.getHandRotation()) + direction: Quat.getUp(this.getHandRotation()), + length: PICK_MAX_DISTANCE + }; + var palmPickRay = { + origin: handPosition, + direction: Quat.getFront(this.getHandRotation()), + length: NEAR_PICK_MAX_DISTANCE }; - this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); + this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); // don't pick 60x per second. do this check after updating the line so it's not jumpy. var now = Date.now(); @@ -270,67 +276,54 @@ function MyController(hand, triggerAction) { } this.lastPickTime = now; - var intersection = Entities.findRayIntersection(pickRay, true); - if (intersection.intersects && intersection.properties.locked === 0) { - // the ray is intersecting something we can move. - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); - this.grabbedEntity = intersection.entityID; + var pickRays = [distantPickRay, palmPickRay]; + for (var index=0; index < pickRays.length; ++index) { + var pickRay = pickRays[index]; + var directionNormalized = Vec3.normalize(pickRay.direction); + var directionBacked = Vec3.multiply(directionNormalized, PICK_BACKOFF_DISTANCE); + var pickRayBacked = { + origin: Vec3.subtract(pickRay.origin, directionBacked), + direction: pickRay.direction + }; - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, DEFAULT_GRABBABLE_DATA); - if (grabbableData.grabbable === false) { - this.grabbedEntity = null; - return; - } - if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) { - // the hand is very close to the intersected object. go into close-grabbing mode. - if (intersection.properties.collisionsWillMove === 1) { - this.setState(STATE_NEAR_GRABBING); - } else { - this.setState(STATE_NEAR_GRABBING_NON_COLLIDING); - } - } else { - // don't allow two people to distance grab the same object - if (entityIsGrabbedByOther(intersection.entityID)) { + var intersection = Entities.findRayIntersection(pickRayBacked, true); + if (intersection.intersects && intersection.properties.locked === 0) { + // the ray is intersecting something we can move. + var intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection); + this.grabbedEntity = intersection.entityID; + + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, + intersection.entityID, + DEFAULT_GRABBABLE_DATA); + if (grabbableData.grabbable === false) { this.grabbedEntity = null; - } else { - // the hand is far from the intersected object. go into distance-holding mode + continue; + } + if (intersectionDistance > pickRay.length) { + // too far away for this ray. + continue; + } + if (intersectionDistance <= NEAR_PICK_MAX_DISTANCE) { + // the hand is very close to the intersected object. go into close-grabbing mode. if (intersection.properties.collisionsWillMove === 1) { - this.setState(STATE_DISTANCE_HOLDING); + this.setState(STATE_NEAR_GRABBING); } else { - this.setState(STATE_FAR_GRABBING_NON_COLLIDING); + this.setState(STATE_NEAR_GRABBING_NON_COLLIDING); + } + } else { + // don't allow two people to distance grab the same object + if (entityIsGrabbedByOther(intersection.entityID)) { + this.grabbedEntity = null; + } else { + // the hand is far from the intersected object. go into distance-holding mode + if (intersection.properties.collisionsWillMove === 1) { + this.setState(STATE_DISTANCE_HOLDING); + } else { + this.setState(STATE_FAR_GRABBING_NON_COLLIDING); + } } } } - } else { - // forward ray test failed, try sphere test. - var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); - var minDistance = GRAB_RADIUS; - var i, props, distance; - - for (i = 0; i < nearbyEntities.length; i++) { - - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], DEFAULT_GRABBABLE_DATA); - if (grabbableData.grabbable === false) { - return; - } - - props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); - - distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer") { - this.grabbedEntity = nearbyEntities[i]; - minDistance = distance; - } - } - if (this.grabbedEntity === null) { - // this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else if (props.locked === 0 && props.collisionsWillMove === 1) { - this.setState(STATE_NEAR_GRABBING); - } else if (props.collisionsWillMove === 0) { - // We have grabbed a non-physical object, so we want to trigger a non-colliding event as opposed to a grab event - this.setState(STATE_NEAR_GRABBING_NON_COLLIDING); - } } }; From 5a968e3c96ff4db13414d50040b147053c385f3f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 15:20:04 -0700 Subject: [PATCH 26/33] tweak --- examples/controllers/handControllerGrab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index e6fedd8f25..01c02840cb 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -43,9 +43,9 @@ var PICK_MAX_DISTANCE = 500; // max length of pick-ray var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable. -var NEAR_PICK_MAX_DISTANCE = 0.1; // max length of pick-ray for close grabbing to be selected +var NEAR_PICK_MAX_DISTANCE = 0.2; // max length of pick-ray for close grabbing to be selected var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things -var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object +var PICK_BACKOFF_DISTANCE = 0.1; // helps when hand is intersecting the grabble object ///////////////////////////////////////////////////////////////// // From 6138775270c96e7c5e32f7b71a8b9a275a0f9b22 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 15:40:14 -0700 Subject: [PATCH 27/33] put back support for spatialKey --- examples/controllers/handControllerGrab.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 01c02840cb..78f648f445 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -473,12 +473,23 @@ function MyController(hand, triggerAction) { var handRotation = this.getHandRotation(); var handPosition = this.getHandPosition(); - var objectRotation = grabbedProperties.rotation; - this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); - var currentObjectPosition = grabbedProperties.position; - var offset = Vec3.subtract(currentObjectPosition, handPosition); - this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); + if (grabbableData.spatialKey) { + if (grabbableData.spatialKey.relativePosition) { + this.offsetPosition = grabbableData.spatialKey.relativePosition; + } + if (grabbableData.spatialKey.relativeRotation) { + this.offsetRotation = grabbableData.spatialKey.relativeRotation; + } + } else { + var objectRotation = grabbedProperties.rotation; + this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); + + var currentObjectPosition = grabbedProperties.position; + var offset = Vec3.subtract(currentObjectPosition, handPosition); + this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); + } this.actionID = NULL_ACTION_ID; this.actionID = Entities.addAction("hold", this.grabbedEntity, { From a1cfebc173695dbff90c97c5f356ac5a6922727b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 15:57:15 -0700 Subject: [PATCH 28/33] don't accept incoming location edits if an entity is being controlled by a shouldSuppressLocationEdits action --- libraries/entities/src/EntityTree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 6e487cbfe3..8449ce050b 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -189,7 +189,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI } else { simulationBlocked = senderID != entity->getSimulatorID(); } - if (simulationBlocked) { + if (simulationBlocked || entity->shouldSuppressLocationEdits()) { // squash ownership and physics-related changes. properties.setSimulationOwnerChanged(false); properties.setPositionChanged(false); From 00594f0ccea027ffa6051cacedc231ee650ead1b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 16:05:10 -0700 Subject: [PATCH 29/33] don't accept incoming location edits if an entity is being controlled by a shouldSuppressLocationEdits action --- libraries/entities/src/EntityItem.cpp | 24 ++++++++++++++++++++++++ libraries/entities/src/EntityItem.h | 8 ++++---- libraries/entities/src/EntityTree.cpp | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 9b3821b56a..3eb8a84bca 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1808,3 +1808,27 @@ bool EntityItem::shouldSuppressLocationEdits() const { return false; } + +void EntityItem::setPosition(const glm::vec3& value) { + if (!entity->shouldSuppressLocationEdits()) { + _transform.setTranslation(value); requiresRecalcBoxes(); + } +} + +void EntityItem::setRotation(const glm::quat& rotation) { + if (!entity->shouldSuppressLocationEdits()) { + _transform.setRotation(rotation); requiresRecalcBoxes(); + } +} + +void EntityItem::setVelocity(const glm::vec3& value) { + if (!entity->shouldSuppressLocationEdits()) { + _velocity = value; + } +} + +void EntityItem::setAcceleration(const glm::vec3& value) { + if (!entity->shouldSuppressLocationEdits()) { + _acceleration = value; + } +} diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 858dc7e326..172ff79276 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -209,10 +209,10 @@ public: /// Position in meters (-TREE_SCALE - TREE_SCALE) inline const glm::vec3& getPosition() const { return _transform.getTranslation(); } - inline void setPosition(const glm::vec3& value) { _transform.setTranslation(value); requiresRecalcBoxes(); } + void setPosition(const glm::vec3& value); inline const glm::quat& getRotation() const { return _transform.getRotation(); } - inline void setRotation(const glm::quat& rotation) { _transform.setRotation(rotation); requiresRecalcBoxes(); } + inline void setRotation(const glm::quat& rotation); inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; } @@ -240,7 +240,7 @@ public: float getDensity() const { return _density; } const glm::vec3& getVelocity() const { return _velocity; } /// get velocity in meters - void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in meters + void setVelocity(const glm::vec3& value); bool hasVelocity() const { return _velocity != ENTITY_ITEM_ZERO_VEC3; } const glm::vec3& getGravity() const { return _gravity; } /// get gravity in meters @@ -248,7 +248,7 @@ public: bool hasGravity() const { return _gravity != ENTITY_ITEM_ZERO_VEC3; } const glm::vec3& getAcceleration() const { return _acceleration; } /// get acceleration in meters/second/second - void setAcceleration(const glm::vec3& value) { _acceleration = value; } /// acceleration in meters/second/second + void setAcceleration(const glm::vec3& value); /// acceleration in meters/second/second bool hasAcceleration() const { return _acceleration != ENTITY_ITEM_ZERO_VEC3; } float getDamping() const { return _damping; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 8449ce050b..6e487cbfe3 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -189,7 +189,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI } else { simulationBlocked = senderID != entity->getSimulatorID(); } - if (simulationBlocked || entity->shouldSuppressLocationEdits()) { + if (simulationBlocked) { // squash ownership and physics-related changes. properties.setSimulationOwnerChanged(false); properties.setPositionChanged(false); From 9e24542c0b1e89913072b39ed0b3f2a42816eefc Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 16:05:56 -0700 Subject: [PATCH 30/33] don't accept incoming location edits if an entity is being controlled by a shouldSuppressLocationEdits action --- libraries/entities/src/EntityItem.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 3eb8a84bca..00ba6e8d42 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1810,25 +1810,25 @@ bool EntityItem::shouldSuppressLocationEdits() const { } void EntityItem::setPosition(const glm::vec3& value) { - if (!entity->shouldSuppressLocationEdits()) { + if (!shouldSuppressLocationEdits()) { _transform.setTranslation(value); requiresRecalcBoxes(); } } void EntityItem::setRotation(const glm::quat& rotation) { - if (!entity->shouldSuppressLocationEdits()) { + if (!shouldSuppressLocationEdits()) { _transform.setRotation(rotation); requiresRecalcBoxes(); } } void EntityItem::setVelocity(const glm::vec3& value) { - if (!entity->shouldSuppressLocationEdits()) { + if (!shouldSuppressLocationEdits()) { _velocity = value; } } void EntityItem::setAcceleration(const glm::vec3& value) { - if (!entity->shouldSuppressLocationEdits()) { + if (!shouldSuppressLocationEdits()) { _acceleration = value; } } From bddbe89c865b228b43496f0c73942cb00d93e661 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 16:13:53 -0700 Subject: [PATCH 31/33] don't accept incoming location edits if an entity is being controlled by a shouldSuppressLocationEdits action --- libraries/entities/src/EntityItem.cpp | 36 +++++++++------------------ libraries/entities/src/EntityItem.h | 8 +++--- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 00ba6e8d42..1fd9acc1e2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1301,6 +1301,9 @@ void EntityItem::computeShapeInfo(ShapeInfo& info) { } void EntityItem::updatePosition(const glm::vec3& value) { + if (shouldSuppressLocationEdits()) { + return; + } auto delta = glm::distance(getPosition(), value); if (delta > IGNORE_POSITION_DELTA) { _dirtyFlags |= Simulation::DIRTY_POSITION; @@ -1323,6 +1326,9 @@ void EntityItem::updateDimensions(const glm::vec3& value) { } void EntityItem::updateRotation(const glm::quat& rotation) { + if (shouldSuppressLocationEdits()) { + return; + } if (getRotation() != rotation) { setRotation(rotation); @@ -1363,6 +1369,9 @@ void EntityItem::updateMass(float mass) { } void EntityItem::updateVelocity(const glm::vec3& value) { + if (shouldSuppressLocationEdits()) { + return; + } auto delta = glm::distance(_velocity, value); if (delta > IGNORE_LINEAR_VELOCITY_DELTA) { _dirtyFlags |= Simulation::DIRTY_LINEAR_VELOCITY; @@ -1399,6 +1408,9 @@ void EntityItem::updateGravity(const glm::vec3& value) { } void EntityItem::updateAngularVelocity(const glm::vec3& value) { + if (shouldSuppressLocationEdits()) { + return; + } auto delta = glm::distance(_angularVelocity, value); if (delta > IGNORE_ANGULAR_VELOCITY_DELTA) { _dirtyFlags |= Simulation::DIRTY_ANGULAR_VELOCITY; @@ -1808,27 +1820,3 @@ bool EntityItem::shouldSuppressLocationEdits() const { return false; } - -void EntityItem::setPosition(const glm::vec3& value) { - if (!shouldSuppressLocationEdits()) { - _transform.setTranslation(value); requiresRecalcBoxes(); - } -} - -void EntityItem::setRotation(const glm::quat& rotation) { - if (!shouldSuppressLocationEdits()) { - _transform.setRotation(rotation); requiresRecalcBoxes(); - } -} - -void EntityItem::setVelocity(const glm::vec3& value) { - if (!shouldSuppressLocationEdits()) { - _velocity = value; - } -} - -void EntityItem::setAcceleration(const glm::vec3& value) { - if (!shouldSuppressLocationEdits()) { - _acceleration = value; - } -} diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 172ff79276..858dc7e326 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -209,10 +209,10 @@ public: /// Position in meters (-TREE_SCALE - TREE_SCALE) inline const glm::vec3& getPosition() const { return _transform.getTranslation(); } - void setPosition(const glm::vec3& value); + inline void setPosition(const glm::vec3& value) { _transform.setTranslation(value); requiresRecalcBoxes(); } inline const glm::quat& getRotation() const { return _transform.getRotation(); } - inline void setRotation(const glm::quat& rotation); + inline void setRotation(const glm::quat& rotation) { _transform.setRotation(rotation); requiresRecalcBoxes(); } inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; } @@ -240,7 +240,7 @@ public: float getDensity() const { return _density; } const glm::vec3& getVelocity() const { return _velocity; } /// get velocity in meters - void setVelocity(const glm::vec3& value); + void setVelocity(const glm::vec3& value) { _velocity = value; } /// velocity in meters bool hasVelocity() const { return _velocity != ENTITY_ITEM_ZERO_VEC3; } const glm::vec3& getGravity() const { return _gravity; } /// get gravity in meters @@ -248,7 +248,7 @@ public: bool hasGravity() const { return _gravity != ENTITY_ITEM_ZERO_VEC3; } const glm::vec3& getAcceleration() const { return _acceleration; } /// get acceleration in meters/second/second - void setAcceleration(const glm::vec3& value); /// acceleration in meters/second/second + void setAcceleration(const glm::vec3& value) { _acceleration = value; } /// acceleration in meters/second/second bool hasAcceleration() const { return _acceleration != ENTITY_ITEM_ZERO_VEC3; } float getDamping() const { return _damping; } From 41f7ef1e2e52bff69c0c9879560bfa13dfe9be85 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 16:53:27 -0700 Subject: [PATCH 32/33] cleanups --- examples/controllers/handControllerGrab.js | 6 ++---- interface/src/avatar/AvatarActionHold.cpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 78f648f445..1e77125d00 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -497,8 +497,7 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - lifetime: ACTION_LIFETIME, - // kinematic: true, + lifetime: ACTION_LIFETIME }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; @@ -550,8 +549,7 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - lifetime: ACTION_LIFETIME, - // kinematic: true + lifetime: ACTION_LIFETIME }); this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); } diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 4d07ecb5e3..cf455ea98c 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -175,7 +175,7 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { ok = true; kinematicSetVelocity = EntityActionInterface::extractBooleanArgument("hold", arguments, - "kinematic-set-velocity", ok, false); + "kinematicSetVelocity", ok, false); if (!ok) { _kinematicSetVelocity = false; } From 4feb9dc8c60a6df7eb01e3ff437cc3ba658941ed Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 17:46:34 -0700 Subject: [PATCH 33/33] prepare for possible future coding standard --- interface/src/avatar/AvatarActionHold.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index 042e6a0f25..6badf97e9e 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -41,9 +41,9 @@ private: QUuid _holderID; void doKinematicUpdate(float deltaTimeStep); - bool _kinematic = false; - bool _kinematicSetVelocity = false; - bool _previousSet = false; + bool _kinematic { false }; + bool _kinematicSetVelocity { false }; + bool _previousSet { false }; glm::vec3 _previousPositionalTarget; glm::quat _previousRotationalTarget; };