Merge pull request #13097 from AndrewMeadows/workload-013

workload: stop locally-owned dynamic entities when removed from Bullet simulation
This commit is contained in:
Sam Gateau 2018-05-04 11:53:57 -07:00 committed by GitHub
commit 328e2dc7f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 80 additions and 33 deletions

View file

@ -53,20 +53,29 @@ void SimpleEntitySimulation::updateEntitiesInternal(uint64_t now) {
}
void SimpleEntitySimulation::addEntityInternal(EntityItemPointer entity) {
if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) {
if (entity->getSimulatorID().isNull()) {
QMutexLocker lock(&_mutex);
_simpleKinematicEntities.insert(entity);
entity->setLastSimulated(usecTimestampNow());
}
if (!entity->getSimulatorID().isNull()) {
if (entity->getDynamic()) {
// we don't allow dynamic objects to move without an owner so nothing to do here
} else if (entity->isMovingRelativeToParent()) {
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr != _simpleKinematicEntities.end()) {
_simpleKinematicEntities.insert(entity);
entity->setLastSimulated(usecTimestampNow());
}
}
} else {
QMutexLocker lock(&_mutex);
_entitiesWithSimulationOwner.insert(entity);
_nextStaleOwnershipExpiry = glm::min(_nextStaleOwnershipExpiry, entity->getSimulationOwnershipExpiry());
} else if (entity->getDynamic() && entity->hasLocalVelocity()) {
QMutexLocker lock(&_mutex);
_entitiesThatNeedSimulationOwner.insert(entity);
uint64_t expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD;
_nextOwnerlessExpiry = glm::min(_nextOwnerlessExpiry, expiry);
if (entity->isMovingRelativeToParent()) {
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr != _simpleKinematicEntities.end()) {
_simpleKinematicEntities.insert(entity);
entity->setLastSimulated(usecTimestampNow());
}
}
}
}
@ -77,32 +86,50 @@ void SimpleEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
}
void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
{
QMutexLocker lock(&_mutex);
if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) {
int numKinematicEntities = _simpleKinematicEntities.size();
_simpleKinematicEntities.insert(entity);
if (numKinematicEntities != _simpleKinematicEntities.size()) {
entity->setLastSimulated(usecTimestampNow());
uint32_t flags = entity->getDirtyFlags();
if ((flags & Simulation::DIRTY_SIMULATOR_ID) || (flags & Simulation::DIRTY_VELOCITIES)) {
if (entity->getSimulatorID().isNull()) {
QMutexLocker lock(&_mutex);
_entitiesWithSimulationOwner.remove(entity);
if (entity->getDynamic()) {
// we don't allow dynamic objects to move without an owner
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr != _simpleKinematicEntities.end()) {
_simpleKinematicEntities.erase(itr);
}
} else if (entity->isMovingRelativeToParent()) {
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr != _simpleKinematicEntities.end()) {
_simpleKinematicEntities.insert(entity);
entity->setLastSimulated(usecTimestampNow());
}
} else {
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr != _simpleKinematicEntities.end()) {
_simpleKinematicEntities.erase(itr);
}
}
} else {
_simpleKinematicEntities.remove(entity);
QMutexLocker lock(&_mutex);
_entitiesWithSimulationOwner.insert(entity);
_nextStaleOwnershipExpiry = glm::min(_nextStaleOwnershipExpiry, entity->getSimulationOwnershipExpiry());
_entitiesThatNeedSimulationOwner.remove(entity);
if (entity->isMovingRelativeToParent()) {
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr != _simpleKinematicEntities.end()) {
_simpleKinematicEntities.insert(entity);
entity->setLastSimulated(usecTimestampNow());
}
} else {
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr != _simpleKinematicEntities.end()) {
_simpleKinematicEntities.erase(itr);
}
}
}
}
if (entity->getSimulatorID().isNull()) {
QMutexLocker lock(&_mutex);
_entitiesWithSimulationOwner.remove(entity);
if (entity->getDynamic() && entity->hasLocalVelocity()) {
_entitiesThatNeedSimulationOwner.insert(entity);
uint64_t expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD;
_nextOwnerlessExpiry = glm::min(_nextOwnerlessExpiry, expiry);
}
} else {
QMutexLocker lock(&_mutex);
_entitiesWithSimulationOwner.insert(entity);
_nextStaleOwnershipExpiry = glm::min(_nextStaleOwnershipExpiry, entity->getSimulationOwnershipExpiry());
_entitiesThatNeedSimulationOwner.remove(entity);
}
entity->clearDirtyFlags();
}
@ -131,6 +158,12 @@ void SimpleEntitySimulation::expireStaleOwnerships(uint64_t now) {
uint64_t expiry = entity->getSimulationOwnershipExpiry();
if (now > expiry) {
itemItr = _entitiesWithSimulationOwner.erase(itemItr);
if (entity->getDynamic()) {
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr != _simpleKinematicEntities.end()) {
_simpleKinematicEntities.erase(itr);
}
}
// remove ownership and dirty all the tree elements that contain the it
entity->clearSimulationOwnership();

View file

@ -130,7 +130,21 @@ void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
bool canBeKinematic = region <= workload::Region::R3;
if (motionState) {
if (!shouldBePhysical) {
// the entity should be removed from the physical simulation
if (motionState->isLocallyOwned()) {
// zero velocities by first deactivating the RigidBody
btRigidBody* body = motionState->getRigidBody();
if (body) {
body->forceActivationState(ISLAND_SLEEPING);
motionState->updateSendVelocities(); // has side-effect of zeroing entity velocities for inactive body
}
// send packet to remove ownership
// NOTE: this packet will NOT be resent if lost, but the good news is:
// the entity-server will eventually clear velocity and ownership for timeout
motionState->sendUpdate(_entityPacketSender, _physicsEngine->getNumSubsteps());
}
// remove from the physical simulation
_incomingChanges.remove(motionState);
_physicalObjects.remove(motionState);
removeOwnershipData(motionState);