added bump call in physics engine for when an entity is deleted and may have something resting on top of it

This commit is contained in:
Seth Alves 2015-04-22 15:50:39 -07:00
parent 7781808bea
commit 07a848c9ce
4 changed files with 39 additions and 1 deletions

View file

@ -61,6 +61,8 @@ public:
void clearEntities();
virtual void bump(EntityItem* bumpEntity) {}
EntityTree* getEntityTree() { return _entityTree; }
signals:

View file

@ -269,6 +269,9 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign
return;
}
// in case something is resting on top of this, give it a bump in the simulation.
_simulation->bump(existingEntity);
if (existingEntity->getLocked() && !force) {
if (!ignoreWarnings) {
qCDebug(entities) << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID;

View file

@ -366,6 +366,39 @@ void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) {
}
}
void PhysicsEngine::bump(EntityItem* bumpEntity) {
// If this node is doing something like deleting an entity, scan for contacts involving the
// entity. For each found, flag the other entity involved as being simulated by this node.
lock();
int numManifolds = _collisionDispatcher->getNumManifolds();
for (int i = 0; i < numManifolds; ++i) {
btPersistentManifold* contactManifold = _collisionDispatcher->getManifoldByIndexInternal(i);
if (contactManifold->getNumContacts() > 0) {
const btCollisionObject* objectA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
const btCollisionObject* objectB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
if (objectA && objectB) {
void* a = objectA->getUserPointer();
void* b = objectB->getUserPointer();
if (a && b) {
EntityItem* entityA = a ? static_cast<EntityMotionState*>(a)->getEntity() : NULL;
EntityItem* entityB = b ? static_cast<EntityMotionState*>(b)->getEntity() : NULL;
if (entityA && entityB) {
if (entityA == bumpEntity) {
entityB->setShouldClaimSimulationOwnership(true);
}
if (entityB == bumpEntity) {
entityA->setShouldClaimSimulationOwnership(true);
}
}
}
}
}
}
unlock();
}
void PhysicsEngine::computeCollisionEvents() {
BT_PROFILE("computeCollisionEvents");
@ -422,7 +455,6 @@ void PhysicsEngine::computeCollisionEvents() {
// scan known contacts and trigger events
ContactMap::iterator contactItr = _contactMap.begin();
while (contactItr != _contactMap.end()) {
ObjectMotionState* A = static_cast<ObjectMotionState*>(contactItr->first._a);
ObjectMotionState* B = static_cast<ObjectMotionState*>(contactItr->first._b);

View file

@ -68,6 +68,7 @@ public:
void stepSimulation();
void stepNonPhysicalKinematics(const quint64& now);
virtual void bump(EntityItem* bumpEntity);
void computeCollisionEvents();
void dumpStatsIfNecessary();