fix bug that was causing spring action to cause constant re-insertion of its rigidbody into bullet. store UUIDs rather than shared pointers in _objectDynamicsByBody so that refcounting works right and actions get their destructors called.

This commit is contained in:
Seth Alves 2017-04-14 11:06:40 -07:00
parent f5a5369055
commit 2dab3069da
6 changed files with 22 additions and 10 deletions

View file

@ -2010,7 +2010,6 @@ bool EntityItem::updateAction(EntitySimulationPointer simulation, const QUuid& a
action->setIsMine(true);
serializeActions(success, _allActionsDataCache);
_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
_dirtyFlags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar
} else {
qCDebug(entities) << "EntityItem::updateAction failed";
}

View file

@ -32,7 +32,7 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta
});
if (!ownerEntity) {
qCDebug(physics) << "warning -- action with no entity removing self from btCollisionWorld.";
qCDebug(physics) << "warning -- action [" << _tag << "] with no entity removing self from btCollisionWorld.";
btDynamicsWorld* dynamicsWorld = static_cast<btDynamicsWorld*>(collisionWorld);
if (dynamicsWorld) {
dynamicsWorld->removeAction(this);

View file

@ -20,6 +20,7 @@
class ObjectAction : public btActionInterface, public ObjectDynamic {
public:
ObjectAction(EntityDynamicType type, const QUuid& id, EntityItemPointer ownerEntity);
virtual ~ObjectAction() {}
virtual bool isAction() const override { return true; }

View file

@ -21,6 +21,8 @@ class ObjectConstraint : public ObjectDynamic
{
public:
ObjectConstraint(EntityDynamicType type, const QUuid& id, EntityItemPointer ownerEntity);
virtual ~ObjectConstraint() {}
virtual btTypedConstraint* getConstraint() = 0;
virtual bool isConstraint() const override { return true; }

View file

@ -145,10 +145,18 @@ void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) {
QList<EntityDynamicPointer> PhysicsEngine::removeDynamicsForBody(btRigidBody* body) {
// remove dynamics that are attached to this body
QList<EntityDynamicPointer> removedDynamics;
QMutableSetIterator<EntityDynamicPointer> i(_objectDynamicsByBody[body]);
QMutableSetIterator<QUuid> i(_objectDynamicsByBody[body]);
while (i.hasNext()) {
EntityDynamicPointer dynamic = i.next();
removeDynamic(dynamic->getID());
QUuid dynamicID = i.next();
if (dynamicID.isNull()) {
continue;
}
EntityDynamicPointer dynamic = _objectDynamics[dynamicID];
if (!dynamic) {
continue;
}
removeDynamic(dynamicID);
removedDynamics += dynamic;
}
return removedDynamics;
@ -608,7 +616,7 @@ bool PhysicsEngine::addDynamic(EntityDynamicPointer dynamic) {
if (success) {
_objectDynamics[dynamicID] = dynamic;
foreach(btRigidBody* rigidBody, std::static_pointer_cast<ObjectDynamic>(dynamic)->getRigidBodies()) {
_objectDynamicsByBody[rigidBody] += dynamic;
_objectDynamicsByBody[rigidBody] += dynamic->getID();
}
}
return success;
@ -632,16 +640,18 @@ void PhysicsEngine::removeDynamic(const QUuid dynamicID) {
}
_objectDynamics.remove(dynamicID);
foreach(btRigidBody* rigidBody, rigidBodies) {
_objectDynamicsByBody[rigidBody].remove(dynamic);
_objectDynamicsByBody[rigidBody].remove(dynamic->getID());
}
dynamic->invalidate();
}
}
void PhysicsEngine::forEachDynamic(std::function<void(EntityDynamicPointer)> actor) {
QHashIterator<QUuid, EntityDynamicPointer> iter(_objectDynamics);
QMutableHashIterator<QUuid, EntityDynamicPointer> iter(_objectDynamics);
while (iter.hasNext()) {
iter.next();
actor(iter.value());
if (iter.value()) {
actor(iter.value());
}
}
}

View file

@ -113,7 +113,7 @@ private:
ContactMap _contactMap;
CollisionEvents _collisionEvents;
QHash<QUuid, EntityDynamicPointer> _objectDynamics;
QHash<btRigidBody*, QSet<EntityDynamicPointer>> _objectDynamicsByBody;
QHash<btRigidBody*, QSet<QUuid>> _objectDynamicsByBody;
std::vector<btRigidBody*> _activeStaticBodies;
glm::vec3 _originOffset;