Showing the changes to libraries/physics/src/ObjectActionSpring.cpp (1 of 5 files). Show all
Unified · Split
| @@ -21,9 +21,11 @@ const uint16_t ObjectActionSpring::springVersion = 1; · 20 unmodified lines | |||
| 21 | ObjectActionSpring::ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity) : | 21 | ObjectActionSpring::ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity) : |
| 22 | ObjectAction(ACTION_TYPE_SPRING, id, ownerEntity), | 22 | ObjectAction(ACTION_TYPE_SPRING, id, ownerEntity), |
| 23 | _positionalTarget(glm::vec3(0.0f)), | 23 | _positionalTarget(glm::vec3(0.0f)), |
| 24 | _desiredPositionalTarget(glm::vec3(0.0f)), | ||
| 24 | _linearTimeScale(FLT_MAX), | 25 | _linearTimeScale(FLT_MAX), |
| 25 | _positionalTargetSet(true), | 26 | _positionalTargetSet(true), |
| 26 | _rotationalTarget(glm::quat()), | 27 | _rotationalTarget(glm::quat()), |
| 28 | _desiredRotationalTarget(glm::quat()), | ||
| 27 | _angularTimeScale(FLT_MAX), | 29 | _angularTimeScale(FLT_MAX), |
| 28 | _rotationalTargetSet(true) { | 30 | _rotationalTargetSet(true) { |
| 29 | #if WANT_DEBUG | 31 | #if WANT_DEBUG |
| @@ -37,9 +39,82 @@ ObjectActionSpring::~ObjectActionSpring() { · 7 unmodified lines | |||
| 37 | #endif | 39 | #endif |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 42 | bool ObjectActionSpring::getTarget(float deltaTimeStep, glm::quat& rotation, glm::vec3& position, | ||
| 43 | glm::vec3& linearVelocity, glm::vec3& angularVelocity) { | ||
| 44 | rotation = _desiredRotationalTarget; | ||
| 45 | position = _desiredPositionalTarget; | ||
| 46 | linearVelocity = glm::vec3(); | ||
| 47 | angularVelocity = glm::vec3(); | ||
| 48 | return true; | ||
| 49 | } | ||
| 50 | |||
| 51 | |||
| 52 | bool ObjectActionSpring::prepareForSpringUpdate(btScalar deltaTimeStep) { | ||
| 53 | glm::quat rotation; | ||
| 54 | glm::vec3 position; | ||
| 55 | glm::vec3 linearVelocity; | ||
| 56 | glm::vec3 angularVelocity; | ||
| 57 | |||
| 58 | bool valid = false; | ||
| 59 | int springCount = 0; | ||
| 60 | |||
| 61 | auto ownerEntity = _ownerEntity.lock(); | ||
| 62 | if (!ownerEntity) { | ||
| 63 | return false; | ||
| 64 | } | ||
| 65 | |||
| 66 | QList<EntityActionPointer> springDerivedActions; | ||
| 67 | springDerivedActions.append(ownerEntity->getActionsOfType(ACTION_TYPE_SPRING)); | ||
| 68 | springDerivedActions.append(ownerEntity->getActionsOfType(ACTION_TYPE_HOLD)); | ||
| 69 | |||
| 70 | foreach (EntityActionPointer action, springDerivedActions) { | ||
| 71 | std::shared_ptr<ObjectActionSpring> springAction = std::static_pointer_cast<ObjectActionSpring>(action); | ||
| 72 | glm::quat rotationForAction; | ||
| 73 | glm::vec3 positionForAction; | ||
| 74 | glm::vec3 linearVelocityForAction, angularVelocityForAction; | ||
| 75 | bool success = springAction->getTarget(deltaTimeStep, rotationForAction, | ||
| 76 | positionForAction, linearVelocityForAction, | ||
| 77 | angularVelocityForAction); | ||
| 78 | if (success) { | ||
| 79 | springCount ++; | ||
| 80 | if (springAction.get() == this) { | ||
| 81 | // only use the rotation for this action | ||
| 82 | valid = true; | ||
| 83 | rotation = rotationForAction; | ||
| 84 | } | ||
| 85 | |||
| 86 | position += positionForAction; | ||
| 87 | linearVelocity += linearVelocityForAction; | ||
| 88 | angularVelocity += angularVelocityForAction; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | if (valid && springCount > 0) { | ||
| 93 | position /= springCount; | ||
| 94 | linearVelocity /= springCount; | ||
| 95 | angularVelocity /= springCount; | ||
| 96 | |||
| 97 | withWriteLock([&]{ | ||
| 98 | _positionalTarget = position; | ||
| 99 | _rotationalTarget = rotation; | ||
| 100 | _linearVelocityTarget = linearVelocity; | ||
| 101 | _angularVelocityTarget = angularVelocity; | ||
| 102 | _positionalTargetSet = true; | ||
| 103 | _rotationalTargetSet = true; | ||
| 104 | _active = true; | ||
| 105 | }); | ||
| 106 | } | ||
| 107 | |||
| 108 | return valid; | ||
| 109 | } | ||
| 110 | |||
| 111 | |||
| 40 | void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { | 112 | void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { |
| 41 | // don't risk hanging the thread running the physics simulation | 113 | if (!prepareForSpringUpdate(deltaTimeStep)) { |
| 42 | auto lockResult = withTryReadLock([&]{ | 114 | return; |
| 115 | } | ||
| 116 | |||
| 117 | withReadLock([&]{ | ||
| 43 | auto ownerEntity = _ownerEntity.lock(); | 118 | auto ownerEntity = _ownerEntity.lock(); |
| 44 | if (!ownerEntity) { | 119 | if (!ownerEntity) { |
| 45 | return; | 120 | return; |
| @@ -101,9 +176,6 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { · 55 unmodified lines | |||
| 101 | rigidBody->setAngularVelocity(targetVelocity); | 176 | rigidBody->setAngularVelocity(targetVelocity); |
| 102 | } | 177 | } |
| 103 | }); | 178 | }); |
| 104 | if (!lockResult) { | ||
| 105 | qDebug() << "ObjectActionSpring::updateActionWorker lock failed"; | ||
| 106 | } | ||
| 107 | } | 179 | } |
| 108 | 180 | ||
| 109 | const float MIN_TIMESCALE = 0.1f; | 181 | const float MIN_TIMESCALE = 0.1f; |
| @@ -122,7 +194,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 12 unmodified lines | |||
| 122 | bool ok = true; | 194 | bool ok = true; |
| 123 | positionalTarget = EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false); | 195 | positionalTarget = EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false); |
| 124 | if (!ok) { | 196 | if (!ok) { |
| 125 | positionalTarget = _positionalTarget; | 197 | positionalTarget = _desiredPositionalTarget; |
| 126 | } | 198 | } |
| 127 | ok = true; | 199 | ok = true; |
| 128 | linearTimeScale = EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false); | 200 | linearTimeScale = EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false); |
| @@ -133,7 +205,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 4 unmodified lines | |||
| 133 | ok = true; | 205 | ok = true; |
| 134 | rotationalTarget = EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false); | 206 | rotationalTarget = EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false); |
| 135 | if (!ok) { | 207 | if (!ok) { |
| 136 | rotationalTarget = _rotationalTarget; | 208 | rotationalTarget = _desiredRotationalTarget; |
| 137 | } | 209 | } |
| 138 | 210 | ||
| 139 | ok = true; | 211 | ok = true; |
| @@ -144,9 +216,9 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 4 unmodified lines | |||
| 144 | } | 216 | } |
| 145 | 217 | ||
| 146 | if (somethingChanged || | 218 | if (somethingChanged || |
| 147 | positionalTarget != _positionalTarget || | 219 | positionalTarget != _desiredPositionalTarget || |
| 148 | linearTimeScale != _linearTimeScale || | 220 | linearTimeScale != _linearTimeScale || |
| 149 | rotationalTarget != _rotationalTarget || | 221 | rotationalTarget != _desiredRotationalTarget || |
| 150 | angularTimeScale != _angularTimeScale) { | 222 | angularTimeScale != _angularTimeScale) { |
| 151 | // something changed | 223 | // something changed |
| 152 | needUpdate = true; | 224 | needUpdate = true; |
| @@ -155,9 +227,9 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 2 unmodified lines | |||
| 155 | 227 | ||
| 156 | if (needUpdate) { | 228 | if (needUpdate) { |
| 157 | withWriteLock([&] { | 229 | withWriteLock([&] { |
| 158 | _positionalTarget = positionalTarget; | 230 | _desiredPositionalTarget = positionalTarget; |
| 159 | _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale)); | 231 | _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale)); |
| 160 | _rotationalTarget = rotationalTarget; | 232 | _desiredRotationalTarget = rotationalTarget; |
| 161 | _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale)); | 233 | _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale)); |
| 162 | _active = true; | 234 | _active = true; |
| 163 | 235 | ||
| @@ -177,9 +249,9 @@ QVariantMap ObjectActionSpring::getArguments() { · 13 unmodified lines | |||
| 177 | QVariantMap arguments = ObjectAction::getArguments(); | 249 | QVariantMap arguments = ObjectAction::getArguments(); |
| 178 | withReadLock([&] { | 250 | withReadLock([&] { |
| 179 | arguments["linearTimeScale"] = _linearTimeScale; | 251 | arguments["linearTimeScale"] = _linearTimeScale; |
| 180 | arguments["targetPosition"] = glmToQMap(_positionalTarget); | 252 | arguments["targetPosition"] = glmToQMap(_desiredPositionalTarget); |
| 181 | 253 | ||
| 182 | arguments["targetRotation"] = glmToQMap(_rotationalTarget); | 254 | arguments["targetRotation"] = glmToQMap(_desiredRotationalTarget); |
| 183 | arguments["angularTimeScale"] = _angularTimeScale; | 255 | arguments["angularTimeScale"] = _angularTimeScale; |
| 184 | }); | 256 | }); |
| 185 | return arguments; | 257 | return arguments; |
| @@ -194,10 +266,10 @@ QByteArray ObjectActionSpring::serialize() const { · 8 unmodified lines | |||
| 194 | dataStream << ObjectActionSpring::springVersion; | 266 | dataStream << ObjectActionSpring::springVersion; |
| 195 | 267 | ||
| 196 | withReadLock([&] { | 268 | withReadLock([&] { |
| 197 | dataStream << _positionalTarget; | 269 | dataStream << _desiredPositionalTarget; |
| 198 | dataStream << _linearTimeScale; | 270 | dataStream << _linearTimeScale; |
| 199 | dataStream << _positionalTargetSet; | 271 | dataStream << _positionalTargetSet; |
| 200 | dataStream << _rotationalTarget; | 272 | dataStream << _desiredRotationalTarget; |
| 201 | dataStream << _angularTimeScale; | 273 | dataStream << _angularTimeScale; |
| 202 | dataStream << _rotationalTargetSet; | 274 | dataStream << _rotationalTargetSet; |
| 203 | dataStream << localTimeToServerTime(_expires); | 275 | dataStream << localTimeToServerTime(_expires); |
| @@ -226,11 +298,11 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { · 22 unmodified lines | |||
| 226 | } | 298 | } |
| 227 | 299 | ||
| 228 | withWriteLock([&] { | 300 | withWriteLock([&] { |
| 229 | dataStream >> _positionalTarget; | 301 | dataStream >> _desiredPositionalTarget; |
| 230 | dataStream >> _linearTimeScale; | 302 | dataStream >> _linearTimeScale; |
| 231 | dataStream >> _positionalTargetSet; | 303 | dataStream >> _positionalTargetSet; |
| 232 | 304 | ||
| 233 | dataStream >> _rotationalTarget; | 305 | dataStream >> _desiredRotationalTarget; |
| 234 | dataStream >> _angularTimeScale; | 306 | dataStream >> _angularTimeScale; |
| 235 | dataStream >> _rotationalTargetSet; | 307 | dataStream >> _rotationalTargetSet; |
| 236 | 308 | ||