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 | 21 | ObjectActionSpring::ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity) : |
| 22 | 22 | ObjectAction(ACTION_TYPE_SPRING, id, ownerEntity), |
| 23 | 23 | _positionalTarget(glm::vec3(0.0f)), |
| 24 | + _desiredPositionalTarget(glm::vec3(0.0f)), | |
| 24 | 25 | _linearTimeScale(FLT_MAX), |
| 25 | 26 | _positionalTargetSet(true), |
| 26 | 27 | _rotationalTarget(glm::quat()), |
| 28 | + _desiredRotationalTarget(glm::quat()), | |
| 27 | 29 | _angularTimeScale(FLT_MAX), |
| 28 | 30 | _rotationalTargetSet(true) { |
| 29 | 31 | #if WANT_DEBUG |
| @@ -37,9 +39,82 @@ ObjectActionSpring::~ObjectActionSpring() { · 7 unmodified lines | ||
| 37 | 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 | 112 | void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { |
| 41 | − // don't risk hanging the thread running the physics simulation | |
| 42 | − auto lockResult = withTryReadLock([&]{ | |
| 113 | + if (!prepareForSpringUpdate(deltaTimeStep)) { | |
| 114 | + return; | |
| 115 | + } | |
| 116 | + | |
| 117 | + withReadLock([&]{ | |
| 43 | 118 | auto ownerEntity = _ownerEntity.lock(); |
| 44 | 119 | if (!ownerEntity) { |
| 45 | 120 | return; |
| @@ -101,9 +176,6 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { · 55 unmodified lines | ||
| 101 | 176 | rigidBody->setAngularVelocity(targetVelocity); |
| 102 | 177 | } |
| 103 | 178 | }); |
| 104 | − if (!lockResult) { | |
| 105 | − qDebug() << "ObjectActionSpring::updateActionWorker lock failed"; | |
| 106 | − } | |
| 107 | 179 | } |
| 108 | 180 | |
| 109 | 181 | const float MIN_TIMESCALE = 0.1f; |
| @@ -122,7 +194,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 12 unmodified lines | ||
| 122 | 194 | bool ok = true; |
| 123 | 195 | positionalTarget = EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false); |
| 124 | 196 | if (!ok) { |
| 125 | − positionalTarget = _positionalTarget; | |
| 197 | + positionalTarget = _desiredPositionalTarget; | |
| 126 | 198 | } |
| 127 | 199 | ok = true; |
| 128 | 200 | linearTimeScale = EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false); |
| @@ -133,7 +205,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 4 unmodified lines | ||
| 133 | 205 | ok = true; |
| 134 | 206 | rotationalTarget = EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false); |
| 135 | 207 | if (!ok) { |
| 136 | − rotationalTarget = _rotationalTarget; | |
| 208 | + rotationalTarget = _desiredRotationalTarget; | |
| 137 | 209 | } |
| 138 | 210 | |
| 139 | 211 | ok = true; |
| @@ -144,9 +216,9 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 4 unmodified lines | ||
| 144 | 216 | } |
| 145 | 217 | |
| 146 | 218 | if (somethingChanged || |
| 147 | − positionalTarget != _positionalTarget || | |
| 219 | + positionalTarget != _desiredPositionalTarget || | |
| 148 | 220 | linearTimeScale != _linearTimeScale || |
| 149 | − rotationalTarget != _rotationalTarget || | |
| 221 | + rotationalTarget != _desiredRotationalTarget || | |
| 150 | 222 | angularTimeScale != _angularTimeScale) { |
| 151 | 223 | // something changed |
| 152 | 224 | needUpdate = true; |
| @@ -155,9 +227,9 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 2 unmodified lines | ||
| 155 | 227 | |
| 156 | 228 | if (needUpdate) { |
| 157 | 229 | withWriteLock([&] { |
| 158 | − _positionalTarget = positionalTarget; | |
| 230 | + _desiredPositionalTarget = positionalTarget; | |
| 159 | 231 | _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale)); |
| 160 | − _rotationalTarget = rotationalTarget; | |
| 232 | + _desiredRotationalTarget = rotationalTarget; | |
| 161 | 233 | _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale)); |
| 162 | 234 | _active = true; |
| 163 | 235 | |
| @@ -177,9 +249,9 @@ QVariantMap ObjectActionSpring::getArguments() { · 13 unmodified lines | ||
| 177 | 249 | QVariantMap arguments = ObjectAction::getArguments(); |
| 178 | 250 | withReadLock([&] { |
| 179 | 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 | 255 | arguments["angularTimeScale"] = _angularTimeScale; |
| 184 | 256 | }); |
| 185 | 257 | return arguments; |
| @@ -194,10 +266,10 @@ QByteArray ObjectActionSpring::serialize() const { · 8 unmodified lines | ||
| 194 | 266 | dataStream << ObjectActionSpring::springVersion; |
| 195 | 267 | |
| 196 | 268 | withReadLock([&] { |
| 197 | − dataStream << _positionalTarget; | |
| 269 | + dataStream << _desiredPositionalTarget; | |
| 198 | 270 | dataStream << _linearTimeScale; |
| 199 | 271 | dataStream << _positionalTargetSet; |
| 200 | − dataStream << _rotationalTarget; | |
| 272 | + dataStream << _desiredRotationalTarget; | |
| 201 | 273 | dataStream << _angularTimeScale; |
| 202 | 274 | dataStream << _rotationalTargetSet; |
| 203 | 275 | dataStream << localTimeToServerTime(_expires); |
| @@ -226,11 +298,11 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { · 22 unmodified lines | ||
| 226 | 298 | } |
| 227 | 299 | |
| 228 | 300 | withWriteLock([&] { |
| 229 | − dataStream >> _positionalTarget; | |
| 301 | + dataStream >> _desiredPositionalTarget; | |
| 230 | 302 | dataStream >> _linearTimeScale; |
| 231 | 303 | dataStream >> _positionalTargetSet; |
| 232 | 304 | |
| 233 | − dataStream >> _rotationalTarget; | |
| 305 | + dataStream >> _desiredRotationalTarget; | |
| 234 | 306 | dataStream >> _angularTimeScale; |
| 235 | 307 | dataStream >> _rotationalTargetSet; |
| 236 | 308 | |