From 7ce0ef2ec456cf95b3f6f96c7a795f6fae7bba72 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 30 Apr 2017 10:04:07 -0700 Subject: [PATCH] fix spring action so that it can be linear or rotational or both --- interface/src/avatar/AvatarActionHold.cpp | 6 +- interface/src/avatar/AvatarActionHold.h | 3 +- libraries/physics/src/ObjectActionSpring.cpp | 91 ++++++++++++-------- libraries/physics/src/ObjectActionSpring.h | 3 +- 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 98ff687eb3..627dc2ba02 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -113,7 +113,8 @@ void AvatarActionHold::prepareForPhysicsSimulation() { } bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position, - glm::vec3& linearVelocity, glm::vec3& angularVelocity) { + glm::vec3& linearVelocity, glm::vec3& angularVelocity, + float& linearTimeScale, float& angularTimeScale) { auto avatarManager = DependencyManager::get(); auto holdingAvatar = std::static_pointer_cast(avatarManager->getAvatarBySessionID(_holderID)); @@ -213,6 +214,9 @@ bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm:: // update linearVelocity based on offset via _relativePosition; linearVelocity = linearVelocity + glm::cross(angularVelocity, position - palmPosition); + + linearTimeScale = _linearTimeScale; + angularTimeScale = _angularTimeScale; }); return true; diff --git a/interface/src/avatar/AvatarActionHold.h b/interface/src/avatar/AvatarActionHold.h index f0b42111ed..7eeda53e06 100644 --- a/interface/src/avatar/AvatarActionHold.h +++ b/interface/src/avatar/AvatarActionHold.h @@ -38,7 +38,8 @@ public: bool getAvatarRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation); virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position, - glm::vec3& linearVelocity, glm::vec3& angularVelocity) override; + glm::vec3& linearVelocity, glm::vec3& angularVelocity, + float& linearTimeScale, float& angularTimeScale) override; virtual void prepareForPhysicsSimulation() override; diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index df7e5f87a3..7c35806bf0 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -16,6 +16,7 @@ #include "PhysicsLogging.h" const float SPRING_MAX_SPEED = 10.0f; +const float MAX_SPRING_TIMESCALE = 600.0f; // 10 min is a long time const uint16_t ObjectActionSpring::springVersion = 1; @@ -42,11 +43,16 @@ ObjectActionSpring::~ObjectActionSpring() { } bool ObjectActionSpring::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position, - glm::vec3& linearVelocity, glm::vec3& angularVelocity) { - rotation = _desiredRotationalTarget; - position = _desiredPositionalTarget; - linearVelocity = glm::vec3(); - angularVelocity = glm::vec3(); + glm::vec3& linearVelocity, glm::vec3& angularVelocity, + float& linearTimeScale, float& angularTimeScale) { + withReadLock([&]{ + rotation = _desiredRotationalTarget; + position = _desiredPositionalTarget; + linearVelocity = glm::vec3(); + angularVelocity = glm::vec3(); + linearTimeScale = _linearTimeScale; + angularTimeScale = _angularTimeScale; + }); return true; } @@ -61,8 +67,10 @@ bool ObjectActionSpring::prepareForSpringUpdate(btScalar deltaTimeStep) { glm::vec3 linearVelocity; glm::vec3 angularVelocity; - bool valid = false; - int springCount = 0; + bool linearValid = false; + int linearSpringCount = 0; + bool angularValid = false; + int angularSpringCount = 0; QList springDerivedActions; springDerivedActions.append(ownerEntity->getActionsOfType(DYNAMIC_TYPE_SPRING)); @@ -73,41 +81,55 @@ bool ObjectActionSpring::prepareForSpringUpdate(btScalar deltaTimeStep) { std::shared_ptr springAction = std::static_pointer_cast(action); glm::quat rotationForAction; glm::vec3 positionForAction; - glm::vec3 linearVelocityForAction, angularVelocityForAction; - bool success = springAction->getTarget(deltaTimeStep, rotationForAction, - positionForAction, linearVelocityForAction, - angularVelocityForAction); + glm::vec3 linearVelocityForAction; + glm::vec3 angularVelocityForAction; + float linearTimeScale; + float angularTimeScale; + bool success = springAction->getTarget(deltaTimeStep, + rotationForAction, positionForAction, + linearVelocityForAction, angularVelocityForAction, + linearTimeScale, angularTimeScale); if (success) { - springCount ++; - if (springAction.get() == this) { - // only use the rotation for this action - valid = true; - rotation = rotationForAction; + if (angularTimeScale < MAX_SPRING_TIMESCALE) { + angularValid = true; + angularSpringCount++; + angularVelocity += angularVelocityForAction; + if (springAction.get() == this) { + // only use the rotation for this action + rotation = rotationForAction; + } } - position += positionForAction; - linearVelocity += linearVelocityForAction; - angularVelocity += angularVelocityForAction; + if (linearTimeScale < MAX_SPRING_TIMESCALE) { + linearValid = true; + linearSpringCount++; + position += positionForAction; + linearVelocity += linearVelocityForAction; + } } } - if (valid && springCount > 0) { - position /= springCount; - linearVelocity /= springCount; - angularVelocity /= springCount; - + if ((angularValid && angularSpringCount > 0) || (linearValid && linearSpringCount > 0)) { withWriteLock([&]{ - _positionalTarget = position; - _rotationalTarget = rotation; - _linearVelocityTarget = linearVelocity; - _angularVelocityTarget = angularVelocity; - _positionalTargetSet = true; - _rotationalTargetSet = true; - _active = true; + if (linearValid && linearSpringCount > 0) { + position /= linearSpringCount; + linearVelocity /= linearSpringCount; + _positionalTarget = position; + _linearVelocityTarget = linearVelocity; + _positionalTargetSet = true; + _active = true; + } + if (angularValid && angularSpringCount > 0) { + angularVelocity /= angularSpringCount; + _rotationalTarget = rotation; + _angularVelocityTarget = angularVelocity; + _rotationalTargetSet = true; + _active = true; + } }); } - return valid; + return linearValid || angularValid; } @@ -133,8 +155,7 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { return; } - const float MAX_TIMESCALE = 600.0f; // 10 min is a long time - if (_linearTimeScale < MAX_TIMESCALE) { + if (_linearTimeScale < MAX_SPRING_TIMESCALE) { btVector3 targetVelocity(0.0f, 0.0f, 0.0f); btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget); float offsetLength = offset.length(); @@ -150,7 +171,7 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { rigidBody->setLinearVelocity(targetVelocity); } - if (_angularTimeScale < MAX_TIMESCALE) { + if (_angularTimeScale < MAX_SPRING_TIMESCALE) { btVector3 targetVelocity(0.0f, 0.0f, 0.0f); btQuaternion bodyRotation = rigidBody->getOrientation(); diff --git a/libraries/physics/src/ObjectActionSpring.h b/libraries/physics/src/ObjectActionSpring.h index de9562d3fa..83a65b36b4 100644 --- a/libraries/physics/src/ObjectActionSpring.h +++ b/libraries/physics/src/ObjectActionSpring.h @@ -28,7 +28,8 @@ public: virtual void deserialize(QByteArray serializedArguments) override; virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position, - glm::vec3& linearVelocity, glm::vec3& angularVelocity); + glm::vec3& linearVelocity, glm::vec3& angularVelocity, + float& linearTimeScale, float& angularTimeScale); protected: static const uint16_t springVersion;