From 9e08dadaf40d05df5824935981b62406ef937474 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 15 May 2017 22:11:42 -0700 Subject: [PATCH] Remove ObjectActionSpring --- interface/src/InterfaceDynamicFactory.cpp | 4 +- .../entities/src/EntityDynamicInterface.cpp | 8 +- .../entities/src/EntityDynamicInterface.h | 9 - libraries/physics/src/ObjectActionSpring.cpp | 378 ------------------ libraries/physics/src/ObjectActionSpring.h | 56 --- 5 files changed, 6 insertions(+), 449 deletions(-) delete mode 100644 libraries/physics/src/ObjectActionSpring.cpp delete mode 100644 libraries/physics/src/ObjectActionSpring.h diff --git a/interface/src/InterfaceDynamicFactory.cpp b/interface/src/InterfaceDynamicFactory.cpp index 49edaae90f..1bb33a7341 100644 --- a/interface/src/InterfaceDynamicFactory.cpp +++ b/interface/src/InterfaceDynamicFactory.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -33,7 +32,8 @@ EntityDynamicPointer interfaceDynamicFactory(EntityDynamicType type, const QUuid case DYNAMIC_TYPE_OFFSET: return std::make_shared(id, ownerEntity); case DYNAMIC_TYPE_SPRING: - return std::make_shared(id, ownerEntity); + // the old "Spring" action moved to "Tractor" + return std::make_shared(id, ownerEntity); case DYNAMIC_TYPE_TRACTOR: return std::make_shared(id, ownerEntity); case DYNAMIC_TYPE_HOLD: diff --git a/libraries/entities/src/EntityDynamicInterface.cpp b/libraries/entities/src/EntityDynamicInterface.cpp index 822ac1c9d6..4bcb0a6027 100644 --- a/libraries/entities/src/EntityDynamicInterface.cpp +++ b/libraries/entities/src/EntityDynamicInterface.cpp @@ -43,7 +43,7 @@ | | +--------------------+ +-----------------------+ | | | | - | ObjectActionSpring | | ObjectConstraintHinge | + | ObjectActionTractor| | ObjectConstraintHinge | | (physics) | | (physics) | +--------------------+ +-----------------------+ @@ -60,7 +60,7 @@ script or when receiving information via an EntityTree data-stream (either over svo file). In the interface, if an EntityItem has dynamics, this EntityItem will have pointers to ObjectDynamic -subclass (like ObjectDynamicSpring) instantiations. Code in the entities library affects a dynamic-object +subclass (like ObjectDynamicTractor) instantiations. Code in the entities library affects a dynamic-object via the EntityDynamicInterface (which knows nothing about bullet). When the ObjectDynamic subclass instance is created, it is registered as a dynamic with bullet. Bullet will call into code in this instance with the btDynamicInterface every physics-simulation step. @@ -75,11 +75,11 @@ right now the AssignmentDynamic class is a place-holder. The dynamic-objects are instantiated by singleton (dependecy) subclasses of EntityDynamicFactoryInterface. In the interface, the subclass is an InterfaceDynamicFactory and it will produce things like -ObjectDynamicSpring. In an entity-server the subclass is an AssignmentDynamicFactory and it always +ObjectDynamicTractor. In an entity-server the subclass is an AssignmentDynamicFactory and it always produces AssignmentDynamics. Depending on the dynamic's type, it will have various arguments. When a script changes an argument of an -dynamic, the argument-holding member-variables of ObjectDynamicSpring (in this example) are updated and +dynamic, the argument-holding member-variables of ObjectDynamicTractor (in this example) are updated and also serialized into _dynamicData in the EntityItem. Each subclass of ObjectDynamic knows how to serialize and deserialize its own arguments. _dynamicData is what gets sent over the wire or saved in an svo file. When a packet-reader receives data for _dynamicData, it will save it in the EntityItem; this causes the diff --git a/libraries/entities/src/EntityDynamicInterface.h b/libraries/entities/src/EntityDynamicInterface.h index b27e600660..40e39eecf1 100644 --- a/libraries/entities/src/EntityDynamicInterface.h +++ b/libraries/entities/src/EntityDynamicInterface.h @@ -94,15 +94,6 @@ public: QString argumentName, bool& ok, bool required = true); protected: - virtual glm::vec3 getPosition() = 0; - // virtual void setPosition(glm::vec3 position) = 0; - virtual glm::quat getRotation() = 0; - // virtual void setRotation(glm::quat rotation) = 0; - virtual glm::vec3 getLinearVelocity() = 0; - virtual void setLinearVelocity(glm::vec3 linearVelocity) = 0; - virtual glm::vec3 getAngularVelocity() = 0; - virtual void setAngularVelocity(glm::vec3 angularVelocity) = 0; - QUuid _id; EntityDynamicType _type; bool _active { false }; diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp deleted file mode 100644 index 0014d4e914..0000000000 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ /dev/null @@ -1,378 +0,0 @@ -// -// ObjectActionSpring.cpp -// libraries/physics/src -// -// Created by Seth Alves 2015-6-5 -// 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 "ObjectActionSpring.h" - -#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; - - -ObjectActionSpring::ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity) : - ObjectAction(DYNAMIC_TYPE_SPRING, id, ownerEntity), - _positionalTarget(glm::vec3(0.0f)), - _desiredPositionalTarget(glm::vec3(0.0f)), - _linearTimeScale(FLT_MAX), - _positionalTargetSet(true), - _rotationalTarget(glm::quat()), - _desiredRotationalTarget(glm::quat()), - _angularTimeScale(FLT_MAX), - _rotationalTargetSet(true) { - #if WANT_DEBUG - qCDebug(physics) << "ObjectActionSpring::ObjectActionSpring"; - #endif -} - -ObjectActionSpring::~ObjectActionSpring() { - #if WANT_DEBUG - qCDebug(physics) << "ObjectActionSpring::~ObjectActionSpring"; - #endif -} - -bool ObjectActionSpring::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position, - glm::vec3& linearVelocity, glm::vec3& angularVelocity, - float& linearTimeScale, float& angularTimeScale) { - SpatiallyNestablePointer other = getOther(); - withReadLock([&]{ - linearTimeScale = _linearTimeScale; - angularTimeScale = _angularTimeScale; - - if (!_otherID.isNull()) { - if (other) { - rotation = _desiredRotationalTarget * other->getRotation(); - position = other->getRotation() * _desiredPositionalTarget + other->getPosition(); - } else { - // we should have an "other" but can't find it, so disable the spring. - linearTimeScale = FLT_MAX; - angularTimeScale = FLT_MAX; - } - } else { - rotation = _desiredRotationalTarget; - position = _desiredPositionalTarget; - } - linearVelocity = glm::vec3(); - angularVelocity = glm::vec3(); - }); - return true; -} - -bool ObjectActionSpring::prepareForSpringUpdate(btScalar deltaTimeStep) { - auto ownerEntity = _ownerEntity.lock(); - if (!ownerEntity) { - return false; - } - - glm::quat rotation; - glm::vec3 position; - glm::vec3 linearVelocity; - glm::vec3 angularVelocity; - - bool linearValid = false; - int linearSpringCount = 0; - bool angularValid = false; - int angularSpringCount = 0; - - QList springDerivedActions; - springDerivedActions.append(ownerEntity->getActionsOfType(DYNAMIC_TYPE_SPRING)); - springDerivedActions.append(ownerEntity->getActionsOfType(DYNAMIC_TYPE_FAR_GRAB)); - springDerivedActions.append(ownerEntity->getActionsOfType(DYNAMIC_TYPE_HOLD)); - - foreach (EntityDynamicPointer action, springDerivedActions) { - std::shared_ptr springAction = std::static_pointer_cast(action); - glm::quat rotationForAction; - glm::vec3 positionForAction; - glm::vec3 linearVelocityForAction; - glm::vec3 angularVelocityForAction; - float linearTimeScale; - float angularTimeScale; - bool success = springAction->getTarget(deltaTimeStep, - rotationForAction, positionForAction, - linearVelocityForAction, angularVelocityForAction, - linearTimeScale, angularTimeScale); - if (success) { - if (angularTimeScale < MAX_SPRING_TIMESCALE) { - angularValid = true; - angularSpringCount++; - angularVelocity += angularVelocityForAction; - if (springAction.get() == this) { - // only use the rotation for this action - rotation = rotationForAction; - } - } - - if (linearTimeScale < MAX_SPRING_TIMESCALE) { - linearValid = true; - linearSpringCount++; - position += positionForAction; - linearVelocity += linearVelocityForAction; - } - } - } - - if ((angularValid && angularSpringCount > 0) || (linearValid && linearSpringCount > 0)) { - withWriteLock([&]{ - 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 linearValid || angularValid; -} - - -void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { - if (!prepareForSpringUpdate(deltaTimeStep)) { - return; - } - - withReadLock([&]{ - auto ownerEntity = _ownerEntity.lock(); - if (!ownerEntity) { - return; - } - - void* physicsInfo = ownerEntity->getPhysicsInfo(); - if (!physicsInfo) { - return; - } - ObjectMotionState* motionState = static_cast(physicsInfo); - btRigidBody* rigidBody = motionState->getRigidBody(); - if (!rigidBody) { - qCDebug(physics) << "ObjectActionSpring::updateActionWorker no rigidBody"; - return; - } - - if (_linearTimeScale < MAX_SPRING_TIMESCALE) { - btVector3 targetVelocity(0.0f, 0.0f, 0.0f); - btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget); - float offsetLength = offset.length(); - if (offsetLength > FLT_EPSILON) { - float speed = glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED); - targetVelocity = (-speed / offsetLength) * offset; - if (speed > rigidBody->getLinearSleepingThreshold()) { - forceBodyNonStatic(); - rigidBody->activate(); - } - } - // this action is aggresively critically damped and defeats the current velocity - rigidBody->setLinearVelocity(targetVelocity); - } - - if (_angularTimeScale < MAX_SPRING_TIMESCALE) { - btVector3 targetVelocity(0.0f, 0.0f, 0.0f); - - btQuaternion bodyRotation = rigidBody->getOrientation(); - auto alignmentDot = bodyRotation.dot(glmToBullet(_rotationalTarget)); - const float ALMOST_ONE = 0.99999f; - if (glm::abs(alignmentDot) < ALMOST_ONE) { - btQuaternion target = glmToBullet(_rotationalTarget); - if (alignmentDot < 0.0f) { - target = -target; - } - // if dQ is the incremental rotation that gets an object from Q0 to Q1 then: - // - // Q1 = dQ * Q0 - // - // solving for dQ gives: - // - // dQ = Q1 * Q0^ - btQuaternion deltaQ = target * bodyRotation.inverse(); - float speed = deltaQ.getAngle() / _angularTimeScale; - targetVelocity = speed * deltaQ.getAxis(); - if (speed > rigidBody->getAngularSleepingThreshold()) { - rigidBody->activate(); - } - } - // this action is aggresively critically damped and defeats the current velocity - rigidBody->setAngularVelocity(targetVelocity); - } - }); -} - -const float MIN_TIMESCALE = 0.1f; - - -bool ObjectActionSpring::updateArguments(QVariantMap arguments) { - glm::vec3 positionalTarget; - float linearTimeScale; - glm::quat rotationalTarget; - float angularTimeScale; - QUuid otherID; - - - bool needUpdate = false; - bool somethingChanged = ObjectDynamic::updateArguments(arguments); - withReadLock([&]{ - // targets are required, spring-constants are optional - bool ok = true; - positionalTarget = EntityDynamicInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false); - if (!ok) { - positionalTarget = _desiredPositionalTarget; - } - ok = true; - linearTimeScale = EntityDynamicInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false); - if (!ok || linearTimeScale <= 0.0f) { - linearTimeScale = _linearTimeScale; - } - - ok = true; - rotationalTarget = EntityDynamicInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false); - if (!ok) { - rotationalTarget = _desiredRotationalTarget; - } - - ok = true; - angularTimeScale = - EntityDynamicInterface::extractFloatArgument("spring action", arguments, "angularTimeScale", ok, false); - if (!ok) { - angularTimeScale = _angularTimeScale; - } - - ok = true; - otherID = QUuid(EntityDynamicInterface::extractStringArgument("spring action", - arguments, "otherID", ok, false)); - if (!ok) { - otherID = _otherID; - } - - if (somethingChanged || - positionalTarget != _desiredPositionalTarget || - linearTimeScale != _linearTimeScale || - rotationalTarget != _desiredRotationalTarget || - angularTimeScale != _angularTimeScale || - otherID != _otherID) { - // something changed - needUpdate = true; - } - }); - - if (needUpdate) { - withWriteLock([&] { - _desiredPositionalTarget = positionalTarget; - _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale)); - _desiredRotationalTarget = rotationalTarget; - _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale)); - _otherID = otherID; - _active = true; - - auto ownerEntity = _ownerEntity.lock(); - if (ownerEntity) { - ownerEntity->setDynamicDataDirty(true); - ownerEntity->setDynamicDataNeedsTransmit(true); - } - }); - activateBody(); - } - - return true; -} - -QVariantMap ObjectActionSpring::getArguments() { - QVariantMap arguments = ObjectDynamic::getArguments(); - withReadLock([&] { - arguments["linearTimeScale"] = _linearTimeScale; - arguments["targetPosition"] = glmToQMap(_desiredPositionalTarget); - - arguments["targetRotation"] = glmToQMap(_desiredRotationalTarget); - arguments["angularTimeScale"] = _angularTimeScale; - - arguments["otherID"] = _otherID; - }); - return arguments; -} - -void ObjectActionSpring::serializeParameters(QDataStream& dataStream) const { - withReadLock([&] { - dataStream << _desiredPositionalTarget; - dataStream << _linearTimeScale; - dataStream << _positionalTargetSet; - dataStream << _desiredRotationalTarget; - dataStream << _angularTimeScale; - dataStream << _rotationalTargetSet; - dataStream << localTimeToServerTime(_expires); - dataStream << _tag; - dataStream << _otherID; - }); -} - -QByteArray ObjectActionSpring::serialize() const { - QByteArray serializedActionArguments; - QDataStream dataStream(&serializedActionArguments, QIODevice::WriteOnly); - - dataStream << DYNAMIC_TYPE_SPRING; - dataStream << getID(); - dataStream << ObjectActionSpring::springVersion; - - serializeParameters(dataStream); - - return serializedActionArguments; -} - -void ObjectActionSpring::deserializeParameters(QByteArray serializedArguments, QDataStream& dataStream) { - withWriteLock([&] { - dataStream >> _desiredPositionalTarget; - dataStream >> _linearTimeScale; - dataStream >> _positionalTargetSet; - - dataStream >> _desiredRotationalTarget; - dataStream >> _angularTimeScale; - dataStream >> _rotationalTargetSet; - - quint64 serverExpires; - dataStream >> serverExpires; - _expires = serverTimeToLocalTime(serverExpires); - - dataStream >> _tag; - - dataStream >> _otherID; - - _active = true; - }); -} - -void ObjectActionSpring::deserialize(QByteArray serializedArguments) { - QDataStream dataStream(serializedArguments); - - EntityDynamicType type; - dataStream >> type; - assert(type == getType()); - - QUuid id; - dataStream >> id; - assert(id == getID()); - - uint16_t serializationVersion; - dataStream >> serializationVersion; - if (serializationVersion != ObjectActionSpring::springVersion) { - assert(false); - return; - } - - deserializeParameters(serializedArguments, dataStream); -} diff --git a/libraries/physics/src/ObjectActionSpring.h b/libraries/physics/src/ObjectActionSpring.h deleted file mode 100644 index 83a65b36b4..0000000000 --- a/libraries/physics/src/ObjectActionSpring.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// ObjectActionSpring.h -// libraries/physics/src -// -// Created by Seth Alves 2015-6-5 -// 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_ObjectActionSpring_h -#define hifi_ObjectActionSpring_h - -#include "ObjectAction.h" - -class ObjectActionSpring : public ObjectAction { -public: - ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity); - virtual ~ObjectActionSpring(); - - virtual bool updateArguments(QVariantMap arguments) override; - virtual QVariantMap getArguments() override; - - virtual void updateActionWorker(float deltaTimeStep) override; - - virtual QByteArray serialize() const override; - virtual void deserialize(QByteArray serializedArguments) override; - - virtual bool getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position, - glm::vec3& linearVelocity, glm::vec3& angularVelocity, - float& linearTimeScale, float& angularTimeScale); - -protected: - static const uint16_t springVersion; - - glm::vec3 _positionalTarget; - glm::vec3 _desiredPositionalTarget; - float _linearTimeScale; - bool _positionalTargetSet; - - glm::quat _rotationalTarget; - glm::quat _desiredRotationalTarget; - float _angularTimeScale; - bool _rotationalTargetSet; - - glm::vec3 _linearVelocityTarget; - glm::vec3 _angularVelocityTarget; - - virtual bool prepareForSpringUpdate(btScalar deltaTimeStep); - - void serializeParameters(QDataStream& dataStream) const; - void deserializeParameters(QByteArray serializedArguments, QDataStream& dataStream); -}; - -#endif // hifi_ObjectActionSpring_h