VectorOfMotionStates& PhysicalEntitySimulation::getObjectsToAdd() { _tempVector.clear(); SetOfEntities::iterator entityItr = _pendingAdds.begin(); while (entityItr != _pendingAdds.end()) { EntityItemPointer entity = *entityItr; assert(!entity->getPhysicsInfo()); if (!entity->shouldBePhysical()) { // this entity should no longer be on the internal _pendingAdds entityItr = _pendingAdds.erase(entityItr); if (entity->isMoving()) { _simpleKinematicEntities.insert(entity); } } else if (entity->isReadyToComputeShape()) { ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); if (shape) { EntityMotionState* motionState = new EntityMotionState(shape, entity); entity->setPhysicsInfo(static_cast<void*>(motionState)); _physicalObjects.insert(motionState); _tempVector.push_back(motionState); entityItr = _pendingAdds.erase(entityItr); } else { //qDebug() << "Warning! Failed to generate new shape for entity." << entity->getName(); ++entityItr; } } else { ++entityItr; } } return _tempVector; }
void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& result) { result.clear(); QMutexLocker lock(&_mutex); SetOfEntities::iterator entityItr = _entitiesToAddToPhysics.begin(); while (entityItr != _entitiesToAddToPhysics.end()) { EntityItemPointer entity = (*entityItr); assert(!entity->getPhysicsInfo()); if (entity->isDead()) { prepareEntityForDelete(entity); } else if (!entity->shouldBePhysical()) { // this entity should no longer be on the internal _entitiesToAddToPhysics entityItr = _entitiesToAddToPhysics.erase(entityItr); if (entity->isMoving()) { _simpleKinematicEntities.insert(entity); } } else if (entity->isReadyToComputeShape()) { ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); if (shape) { EntityMotionState* motionState = new EntityMotionState(shape, entity); entity->setPhysicsInfo(static_cast<void*>(motionState)); _physicalObjects.insert(motionState); result.push_back(motionState); entityItr = _entitiesToAddToPhysics.erase(entityItr); } else { //qDebug() << "Warning! Failed to generate new shape for entity." << entity->getName(); ++entityItr; } } else { ++entityItr; } } }
void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) { EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo()); if (motionState) { motionState->clearObjectBackPointer(); entity->setPhysicsInfo(nullptr); _pendingRemoves.insert(motionState); _outgoingChanges.remove(motionState); } _pendingAdds.remove(entity); }
VectorOfMotionStates& PhysicalEntitySimulation::getObjectsToDelete() { _tempVector.clear(); for (auto stateItr : _pendingRemoves) { EntityMotionState* motionState = &(*stateItr); _pendingChanges.remove(motionState); _physicalObjects.remove(motionState); EntityItemPointer entity = motionState->getEntity(); if (entity) { _pendingAdds.remove(entity); entity->setPhysicsInfo(nullptr); motionState->clearObjectBackPointer(); } _tempVector.push_back(motionState); } _pendingRemoves.clear(); return _tempVector; }
void PhysicalEntitySimulation::clearEntitiesInternal() { // TODO: we should probably wait to lock the _physicsEngine so we don't mess up data structures // while it is in the middle of a simulation step. As it is, we're probably in shutdown mode // anyway, so maybe the simulation was already properly shutdown? Cross our fingers... // first disconnect each MotionStates from its Entity for (auto stateItr : _physicalObjects) { EntityMotionState* motionState = static_cast<EntityMotionState*>(&(*stateItr)); EntityItemPointer entity = motionState->getEntity(); if (entity) { entity->setPhysicsInfo(nullptr); } motionState->clearObjectBackPointer(); } // then delete the objects (aka MotionStates) _physicsEngine->deleteObjects(_physicalObjects); // finally clear all lists (which now have only dangling pointers) _physicalObjects.clear(); _pendingRemoves.clear(); _pendingAdds.clear(); _pendingChanges.clear(); }