History

try having all spring derived actions agree on a target

Seth Alves committed 10 years ago

Commit 44beca11 parent 5a866405 files · +112 −78Browse files

Showing the changes to libraries/physics/src/ObjectActionSpring.cpp (1 of 5 files). Show all

Unified · Split

libraries/physics/src/ObjectActionSpring.cpp+89−17
@@ -21,9 +21,11 @@ const uint16_t ObjectActionSpring::springVersion = 1; · 20 unmodified lines
2121 ObjectActionSpring::ObjectActionSpring(const QUuid& id, EntityItemPointer ownerEntity) :
2222 ObjectAction(ACTION_TYPE_SPRING, id, ownerEntity),
2323 _positionalTarget(glm::vec3(0.0f)),
24+ _desiredPositionalTarget(glm::vec3(0.0f)),
2425 _linearTimeScale(FLT_MAX),
2526 _positionalTargetSet(true),
2627 _rotationalTarget(glm::quat()),
28+ _desiredRotationalTarget(glm::quat()),
2729 _angularTimeScale(FLT_MAX),
2830 _rotationalTargetSet(true) {
2931 #if WANT_DEBUG
@@ -37,9 +39,82 @@ ObjectActionSpring::~ObjectActionSpring() { · 7 unmodified lines
3739 #endif
3840 }
3941
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+
40112 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([&]{
43118 auto ownerEntity = _ownerEntity.lock();
44119 if (!ownerEntity) {
45120 return;
@@ -101,9 +176,6 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { · 55 unmodified lines
101176 rigidBody->setAngularVelocity(targetVelocity);
102177 }
103178 });
104− if (!lockResult) {
105− qDebug() << "ObjectActionSpring::updateActionWorker lock failed";
106− }
107179 }
108180
109181 const float MIN_TIMESCALE = 0.1f;
@@ -122,7 +194,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 12 unmodified lines
122194 bool ok = true;
123195 positionalTarget = EntityActionInterface::extractVec3Argument("spring action", arguments, "targetPosition", ok, false);
124196 if (!ok) {
125− positionalTarget = _positionalTarget;
197+ positionalTarget = _desiredPositionalTarget;
126198 }
127199 ok = true;
128200 linearTimeScale = EntityActionInterface::extractFloatArgument("spring action", arguments, "linearTimeScale", ok, false);
@@ -133,7 +205,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 4 unmodified lines
133205 ok = true;
134206 rotationalTarget = EntityActionInterface::extractQuatArgument("spring action", arguments, "targetRotation", ok, false);
135207 if (!ok) {
136− rotationalTarget = _rotationalTarget;
208+ rotationalTarget = _desiredRotationalTarget;
137209 }
138210
139211 ok = true;
@@ -144,9 +216,9 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 4 unmodified lines
144216 }
145217
146218 if (somethingChanged ||
147− positionalTarget != _positionalTarget ||
219+ positionalTarget != _desiredPositionalTarget ||
148220 linearTimeScale != _linearTimeScale ||
149− rotationalTarget != _rotationalTarget ||
221+ rotationalTarget != _desiredRotationalTarget ||
150222 angularTimeScale != _angularTimeScale) {
151223 // something changed
152224 needUpdate = true;
@@ -155,9 +227,9 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 2 unmodified lines
155227
156228 if (needUpdate) {
157229 withWriteLock([&] {
158− _positionalTarget = positionalTarget;
230+ _desiredPositionalTarget = positionalTarget;
159231 _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale));
160− _rotationalTarget = rotationalTarget;
232+ _desiredRotationalTarget = rotationalTarget;
161233 _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale));
162234 _active = true;
163235
@@ -177,9 +249,9 @@ QVariantMap ObjectActionSpring::getArguments() { · 13 unmodified lines
177249 QVariantMap arguments = ObjectAction::getArguments();
178250 withReadLock([&] {
179251 arguments["linearTimeScale"] = _linearTimeScale;
180− arguments["targetPosition"] = glmToQMap(_positionalTarget);
252+ arguments["targetPosition"] = glmToQMap(_desiredPositionalTarget);
181253
182− arguments["targetRotation"] = glmToQMap(_rotationalTarget);
254+ arguments["targetRotation"] = glmToQMap(_desiredRotationalTarget);
183255 arguments["angularTimeScale"] = _angularTimeScale;
184256 });
185257 return arguments;
@@ -194,10 +266,10 @@ QByteArray ObjectActionSpring::serialize() const { · 8 unmodified lines
194266 dataStream << ObjectActionSpring::springVersion;
195267
196268 withReadLock([&] {
197− dataStream << _positionalTarget;
269+ dataStream << _desiredPositionalTarget;
198270 dataStream << _linearTimeScale;
199271 dataStream << _positionalTargetSet;
200− dataStream << _rotationalTarget;
272+ dataStream << _desiredRotationalTarget;
201273 dataStream << _angularTimeScale;
202274 dataStream << _rotationalTargetSet;
203275 dataStream << localTimeToServerTime(_expires);
@@ -226,11 +298,11 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { · 22 unmodified lines
226298 }
227299
228300 withWriteLock([&] {
229− dataStream >> _positionalTarget;
301+ dataStream >> _desiredPositionalTarget;
230302 dataStream >> _linearTimeScale;
231303 dataStream >> _positionalTargetSet;
232304
233− dataStream >> _rotationalTarget;
305+ dataStream >> _desiredRotationalTarget;
234306 dataStream >> _angularTimeScale;
235307 dataStream >> _rotationalTargetSet;
236308