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... // copy everything into _entitiesToDelete for (auto stateItr : _physicalObjects) { EntityMotionState* motionState = static_cast<EntityMotionState*>(&(*stateItr)); _entitiesToDelete.insert(motionState->getEntity()); } // then remove the objects (aka MotionStates) from physics _physicsEngine->removeObjects(_physicalObjects); // delete the MotionStates // TODO: after we invert the entities/physics lib dependencies we will let EntityItem delete // its own PhysicsInfo rather than do it here for (auto entity : _entitiesToDelete) { EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo()); if (motionState) { entity->setPhysicsInfo(nullptr); delete motionState; } } // finally clear all lists maintained by this class _physicalObjects.clear(); _entitiesToRemoveFromPhysics.clear(); _entitiesToRelease.clear(); _entitiesToAddToPhysics.clear(); _pendingChanges.clear(); _outgoingChanges.clear(); }
void PhysicalEntitySimulation::handleOutgoingChanges(VectorOfMotionStates& motionStates, const QUuid& sessionID) { // walk the motionStates looking for those that correspond to entities for (auto stateItr : motionStates) { ObjectMotionState* state = &(*stateItr); if (state && state->getType() == MOTIONSTATE_TYPE_ENTITY) { EntityMotionState* entityState = static_cast<EntityMotionState*>(state); EntityItemPointer entity = entityState->getEntity(); if (entity) { if (entityState->isCandidateForOwnership(sessionID)) { _outgoingChanges.insert(entityState); } _entitiesToSort.insert(entityState->getEntity()); } } } uint32_t numSubsteps = _physicsEngine->getNumSubsteps(); if (_lastStepSendPackets != numSubsteps) { _lastStepSendPackets = numSubsteps; if (sessionID.isNull()) { // usually don't get here, but if so --> nothing to do _outgoingChanges.clear(); return; } // send outgoing packets QSet<EntityMotionState*>::iterator stateItr = _outgoingChanges.begin(); while (stateItr != _outgoingChanges.end()) { EntityMotionState* state = *stateItr; if (!state->isCandidateForOwnership(sessionID)) { stateItr = _outgoingChanges.erase(stateItr); } else if (state->shouldSendUpdate(numSubsteps, sessionID)) { state->sendUpdate(_entityPacketSender, sessionID, numSubsteps); ++stateItr; } else { ++stateItr; } } } }
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(); }