History

Fixing some entity race condition crashes

Brad Davis committed 11 years ago

Commit aa989c31 parent c4c6e7236 files · +1364 −1192Browse files

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

Unified · Split

libraries/physics/src/ObjectActionSpring.cpp+71−75
@@ -38,74 +38,72 @@ ObjectActionSpring::~ObjectActionSpring() { · 37 unmodified lines
3838 }
3939
4040 void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
41− if (!tryLockForRead()) {
42− // don't risk hanging the thread running the physics simulation
43− qDebug() << "ObjectActionSpring::updateActionWorker lock failed";
44− return;
45− }
41+ auto lockResult = withTryReadLock([&]{
42+ auto ownerEntity = _ownerEntity.lock();
43+ if (!ownerEntity) {
44+ return;
45+ }
4646
47− auto ownerEntity = _ownerEntity.lock();
48− if (!ownerEntity) {
49− return;
50− }
47+ void* physicsInfo = ownerEntity->getPhysicsInfo();
48+ if (!physicsInfo) {
49+ return;
50+ }
51+ ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
52+ btRigidBody* rigidBody = motionState->getRigidBody();
53+ if (!rigidBody) {
54+ qDebug() << "ObjectActionSpring::updateActionWorker no rigidBody";
55+ return;
56+ }
5157
52− void* physicsInfo = ownerEntity->getPhysicsInfo();
53− if (!physicsInfo) {
54− unlock();
55− return;
56− }
57− ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
58− btRigidBody* rigidBody = motionState->getRigidBody();
59− if (!rigidBody) {
60− unlock();
61− qDebug() << "ObjectActionSpring::updateActionWorker no rigidBody";
62− return;
63− }
58+ const float MAX_TIMESCALE = 600.0f; // 10 min is a long time
59+ if (_linearTimeScale < MAX_TIMESCALE) {
60+ btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget);
61+ float offsetLength = offset.length();
62+ btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
6463
65− const float MAX_TIMESCALE = 600.0f; // 10 min is a long time
66− if (_linearTimeScale < MAX_TIMESCALE) {
67− btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget);
68− float offsetLength = offset.length();
69− btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
64+ if (offsetLength > 0) {
65+ float speed = (offsetLength > FLT_EPSILON) ? glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED) : 0.0f;
66+ targetVelocity = (-speed / offsetLength) * offset;
67+ }
7068
71− if (offsetLength > 0) {
72− float speed = (offsetLength > FLT_EPSILON) ? glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED) : 0.0f;
73− targetVelocity = (-speed / offsetLength) * offset;
69+ // this action is aggresively critically damped and defeats the current velocity
70+ rigidBody->setLinearVelocity(targetVelocity);
7471 }
7572
76− // this action is aggresively critically damped and defeats the current velocity
77− rigidBody->setLinearVelocity(targetVelocity);
78− }
79−
80− if (_angularTimeScale < MAX_TIMESCALE) {
81− btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
82−
83− btQuaternion bodyRotation = rigidBody->getOrientation();
84− auto alignmentDot = bodyRotation.dot(glmToBullet(_rotationalTarget));
85− const float ALMOST_ONE = 0.99999f;
86− if (glm::abs(alignmentDot) < ALMOST_ONE) {
87− btQuaternion target = glmToBullet(_rotationalTarget);
88− if (alignmentDot < 0.0f) {
89− target = -target;
90− }
91− // if dQ is the incremental rotation that gets an object from Q0 to Q1 then:
92− //
93− // Q1 = dQ * Q0
94− //
95− // solving for dQ gives:
96− //
97− // dQ = Q1 * Q0^
98− btQuaternion deltaQ = target * bodyRotation.inverse();
99− float angle = deltaQ.getAngle();
100− const float MIN_ANGLE = 1.0e-4f;
101− if (angle > MIN_ANGLE) {
102− targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis();
73+ if (_angularTimeScale < MAX_TIMESCALE) {
74+ btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
75+
76+ btQuaternion bodyRotation = rigidBody->getOrientation();
77+ auto alignmentDot = bodyRotation.dot(glmToBullet(_rotationalTarget));
78+ const float ALMOST_ONE = 0.99999f;
79+ if (glm::abs(alignmentDot) < ALMOST_ONE) {
80+ btQuaternion target = glmToBullet(_rotationalTarget);
81+ if (alignmentDot < 0.0f) {
82+ target = -target;
83+ }
84+ // if dQ is the incremental rotation that gets an object from Q0 to Q1 then:
85+ //
86+ // Q1 = dQ * Q0
87+ //
88+ // solving for dQ gives:
89+ //
90+ // dQ = Q1 * Q0^
91+ btQuaternion deltaQ = target * bodyRotation.inverse();
92+ float angle = deltaQ.getAngle();
93+ const float MIN_ANGLE = 1.0e-4f;
94+ if (angle > MIN_ANGLE) {
95+ targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis();
96+ }
10397 }
98+ // this action is aggresively critically damped and defeats the current velocity
99+ rigidBody->setAngularVelocity(targetVelocity);
104100 }
105− // this action is aggresively critically damped and defeats the current velocity
106− rigidBody->setAngularVelocity(targetVelocity);
101+ });
102+ if (!lockResult) {
103+ // don't risk hanging the thread running the physics simulation
104+ qDebug() << "ObjectActionSpring::updateActionWorker lock failed";
105+ return;
107106 }
108− unlock();
109107 }
110108
111109 const float MIN_TIMESCALE = 0.1f;
@@ -144,29 +142,27 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { · 32 unmodified lines
144142 || rotationalTarget != _rotationalTarget
145143 || angularTimeScale != _angularTimeScale) {
146144 // something changed
147− lockForWrite();
148− _positionalTarget = positionalTarget;
149− _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale));
150− _rotationalTarget = rotationalTarget;
151− _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale));
152− _active = true;
153− activateBody();
154− unlock();
145+ withWriteLock([&] {
146+ _positionalTarget = positionalTarget;
147+ _linearTimeScale = glm::max(MIN_TIMESCALE, glm::abs(linearTimeScale));
148+ _rotationalTarget = rotationalTarget;
149+ _angularTimeScale = glm::max(MIN_TIMESCALE, glm::abs(angularTimeScale));
150+ _active = true;
151+ activateBody();
152+ });
155153 }
156154 return true;
157155 }
158156
159157 QVariantMap ObjectActionSpring::getArguments() {
160158 QVariantMap arguments;
161− lockForRead();
162−
163− arguments["linearTimeScale"] = _linearTimeScale;
164− arguments["targetPosition"] = glmToQMap(_positionalTarget);
165−
166− arguments["targetRotation"] = glmToQMap(_rotationalTarget);
167− arguments["angularTimeScale"] = _angularTimeScale;
159+ withReadLock([&] {
160+ arguments["linearTimeScale"] = _linearTimeScale;
161+ arguments["targetPosition"] = glmToQMap(_positionalTarget);
168162
169− unlock();
163+ arguments["targetRotation"] = glmToQMap(_rotationalTarget);
164+ arguments["angularTimeScale"] = _angularTimeScale;
165+ });
170166 return arguments;
171167 }
172168